成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Java中多個ifelse語句的替代設(shè)計

izhuhaodev / 3223人閱讀

摘要:但是有可能嵌套的語句只是轉(zhuǎn)移到了工廠類,這違背了我們的目的。這樣可以減少嵌套語句的數(shù)量,并將責(zé)任委托給單個值。一個評估規(guī)則和返回基于輸入的結(jié)果。首先,我們將定義一個接口其次,讓我們實(shí)現(xiàn)一個所述接受一個表達(dá)對象,并返回結(jié)果。

概述

ifelse是任何編程語言的重要組成部分。但是我們編寫了大量嵌套的if語句,這使得我們的代碼更加復(fù)雜和難以維護(hù)。

接下來,讓我們探索如何簡化代碼的中的ifelse語句寫法。

案例研究

我們經(jīng)常遇到涉及很多條件的業(yè)務(wù)邏輯,并且每個邏輯都需要不同的處理方式。以Calculator類為例。我們將有一個方法,它接受兩個數(shù)字和一個運(yùn)算符作為輸入,并根據(jù)操作返回結(jié)果:

public int calculate(int a, int b, String operator) {
    int result = Integer.MIN_VALUE;
 
    if ("add".equals(operator)) {
        result = a + b;
    } else if ("multiply".equals(operator)) {
        result = a * b;
    } else if ("divide".equals(operator)) {
        result = a / b;
    } else if ("subtract".equals(operator)) {
        result = a - b;
    }
    return result;
}

我們也可以使用switch語句來實(shí)現(xiàn)它:

public int calculateUsingSwitch(int a, int b, String operator) {
    switch (operator) {
    case "add":
        result = a + b;
        break;
    // other cases    
    }
    return result;
}

在典型的開發(fā)中,if語句可能會變得更大,更復(fù)雜。此外,當(dāng)存在復(fù)雜條件時,switch語句不適合。

擁有嵌套決策結(jié)構(gòu)的另一個副作用是它們變得難以管理。例如,如果我們需要添加一個新的運(yùn)算符,我們必須添加一個新的if語句并實(shí)現(xiàn)該操作。

重構(gòu)

可以通過設(shè)計模式,來達(dá)到我們要的效果。

工廠模式

很多時候,我們遇到ifelse結(jié)構(gòu),最終在每個分支中執(zhí)行類似的操作。這提供了提取工廠方法的機(jī)會,該工廠方法返回給定類型的對象并基于具體對象行為執(zhí)行操作。

對于我們的示例,讓我們定義一個具有單個apply方法的Operation接口:

public interface Operation {
    int apply(int a, int b);
}

該方法將兩個數(shù)字作為輸入并返回結(jié)果。讓我們定義一個用于執(zhí)行添加的類:

public class Addition implements Operation {
    @Override
    public int apply(int a, int b) {
        return a + b;
    }
}

我們現(xiàn)在將實(shí)現(xiàn)一個工廠類,它根據(jù)給定的運(yùn)算符返回Operation的實(shí)例:

public class OperatorFactory {
    static Map operationMap = new HashMap<>();
    static {
        operationMap.put("add", new Addition());
        operationMap.put("divide", new Division());
        // more operators
    }
 
    public static Optional getOperation(String operator) {
        return Optional.ofNullable(operationMap.get(operator));
    }
}

現(xiàn)在,在Calculator類中,我們可以查詢工廠以獲取相關(guān)操作并應(yīng)用源數(shù):

public int calculateUsingFactory(int a, int b, String operator) {
    Operation targetOperation = OperatorFactory
      .getOperation(operator)
      .orElseThrow(() -> new IllegalArgumentException("Invalid Operator"));
    return targetOperation.apply(a, b);
}

在這個例子中,我們已經(jīng)看到了如何將責(zé)任委托給工廠類提供的松散耦合對象。但是有可能嵌套的if語句只是轉(zhuǎn)移到了工廠類,這違背了我們的目的。

或者,我們可以在Map中維護(hù)一個對象存儲庫,可以查詢該存儲庫以進(jìn)行快速查找。正如我們所見,OperatorFactory#operationMap服務(wù)于我們的目的。我們還可以在運(yùn)行時初始化Map并將它們配置為查找。

使用枚舉

除了使用Map之外,我們還可以使用Enum來標(biāo)記特定的業(yè)務(wù)邏輯。之后,我們可以在嵌套的if語句或switch case 語句中使用它們。或者,我們也可以將它們用作對象的工廠并制定策略以執(zhí)行相關(guān)的業(yè)務(wù)邏輯。

這樣可以減少嵌套if語句的數(shù)量,并將責(zé)任委托給單個Enum值。

讓我們看看我們?nèi)绾螌?shí)現(xiàn)它。首先,我們需要定義我們的枚舉:

public enum Operator {
    ADD, MULTIPLY, SUBTRACT, DIVIDE
}

可以觀察到,這些值是不同運(yùn)算符的標(biāo)簽,將進(jìn)一步用于計算。我們總是可以選擇在嵌套的if語句或switch case中使用這些值作為不同的條件,但讓我們設(shè)計一種將邏輯委托給Enum本身的替代方法。

我們將為每個Enum值定義方法并進(jìn)行計算。例如:

ADD {
    @Override
    public int apply(int a, int b) {
        return a + b;
    }
},
// other operators
 
public abstract int apply(int a, int b);

然后在Calculator類中,我們可以定義一個執(zhí)行操作的方法:

public int calculate(int a, int b, Operator operator) { return operator.apply(a, b); }

現(xiàn)在,我們可以通過使用Operator#valueOf()方法將String值轉(zhuǎn)換為Operator來調(diào)用該方法:

@Test
public void test() {
    Calculator calculator = new Calculator();
    int result = calculator.calculate(3, 4, Operator.valueOf("ADD"));
    assertEquals(7, result);
}
命令模式

在前面的討論中,我們已經(jīng)看到使用工廠類來返回給定運(yùn)算符的正確業(yè)務(wù)對象的實(shí)例。稍后,業(yè)務(wù)對象用于在計算器中執(zhí)行計算。

我們還可以設(shè)計一個Calculator#calculate方法來接受可以在輸入上執(zhí)行的命令。這將是替換嵌套if語句的另一種方法。

我們首先定義我們的Command接口:

public interface Command {
    Integer execute();
}

接下來,讓我們實(shí)現(xiàn)一個AddCommand:

public class AddCommand implements Command {
    // Instance variables
 
    public AddCommand(int a, int b) {
        this.a = a;
        this.b = b;
    }
 
    @Override
    public Integer execute() {
        return a + b;
    }
}

最后,讓我們在Calculator中引入一個接受并執(zhí)行Command的新方法:

public int calculate(Command command) {
    return command.execute();
}

接下來,我們可以通過實(shí)例化AddCommand調(diào)用計算并將其發(fā)送到Calculator#calculate方法:

@Test
public void test() {
    Calculator calculator = new Calculator();
    int result = calculator.calculate(new AddCommand(3, 7));
    assertEquals(10, result);
}
規(guī)則引擎

當(dāng)我們最終編寫大量嵌套if語句時,每個條件都描述了一個業(yè)務(wù)規(guī)則,必須對其進(jìn)行評估才能處理正確的邏輯。規(guī)則引擎從主代碼中獲取了這種復(fù)雜性。一個RuleEngine評估規(guī)則和返回基于輸入的結(jié)果。

讓我們通過設(shè)計一個簡單的RuleEngine來演示一個例子,該RuleEngine通過一組規(guī)則處理Expression并返回所選規(guī)則的結(jié)果。首先,我們將定義一個Rule接口:

public interface Rule {
    boolean evaluate(Expression expression);
    Result getResult();
}

其次,讓我們實(shí)現(xiàn)一個RuleEngine:

public class RuleEngine {
    private static List rules = new ArrayList<>();
 
    static {
        rules.add(new AddRule());
    }
 
    public Result process(Expression expression) {
        Rule rule = rules
          .stream()
          .filter(r -> r.evaluate(expression))
          .findFirst()
          .orElseThrow(() -> new IllegalArgumentException("Expression does not matches any Rule"));
        return rule.getResult();
    }
}

所述RuleEngine接受一個表達(dá)對象,并返回結(jié)果?,F(xiàn)在,讓我們將Expression類設(shè)計為一組包含兩個Integer對象的Operator,它將被應(yīng)用:

public class Expression {
    private Integer x;
    private Integer y;
    private Operator operator;        
}

最后讓我們定義一個自定義的AddRule類,該類僅在指定ADD操作時進(jìn)行求值:

public class AddRule implements Rule {
    @Override
    public boolean evaluate(Expression expression) {
        boolean evalResult = false;
        if (expression.getOperator() == Operator.ADD) {
            this.result = expression.getX() + expression.getY();
            evalResult = true;
        }
        return evalResult;
    }    
}

我們現(xiàn)在將使用Expression調(diào)用RuleEngine:

@Test
public void test() {
    Expression expression = new Expression(5, 5, Operator.ADD);
    RuleEngine engine = new RuleEngine();
    Result result = engine.process(expression);
 
    assertNotNull(result);
    assertEquals(10, result.getValue());
}
結(jié)論

通過這些設(shè)計模式,可以作為我們的ifelse語句的替代方案,具體用哪一種可以根據(jù)你的實(shí)際業(yè)務(wù)場景來決定。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/7866.html

相關(guān)文章

  • Theano - 條件

    摘要:接收布爾型條件和兩個變量作為輸入。進(jìn)行元素級運(yùn)算,因此比更常用。比較懶惰,只計算滿足條件的相應(yīng)輸出變量,而計算所有的輸出變量。如果那么計算和,并輸出在這個例子中,比花費(fèi)更少的時間,因為他只計算輸出變量中的一個。 IfElse vs Switch IfElse接收布爾型條件和兩個變量作為輸入。 Switch接收一個張量(Tensor)以及兩個變量作為輸入。 Switch進(jìn)行元素級運(yùn)算,...

    mengera88 評論0 收藏0
  • Java 高效編程(Effective Java文第三版

    摘要:來源前條來源一書英文版已經(jīng)出版,這本書的第二版想必很多人都讀過,號稱四大名著之一,不過第二版年出版,到現(xiàn)在已經(jīng)將近年的時間,但隨著,,,甚至的發(fā)布,語言發(fā)生了深刻的變化。譯者在這里第一時間翻譯成中文版。供大家學(xué)習(xí)分享之用。 來源:sjsdfg/effective-java-3rd-chinese前 51 條來源:Effective Java, Third Edition 《Effec...

    ysl_unh 評論0 收藏0
  • JavaScript】核心語法之之語句

    JS(JavaScript) 語句 一。概述; 1.語句概述; 在JavaScript中,語句使用分號進(jìn)行分割,可編寫一條語句,也可編寫多條語句條件語句;在JavaScript中根據(jù)判斷是執(zhí)行還是跳過語句循環(huán)語句;在JavaScript中判斷是否重復(fù)執(zhí)行語句跳轉(zhuǎn)語句;在JavaScript中跳轉(zhuǎn)到語句2.語句塊;在JavaScript中使用一對花括號({})表示一個語句塊3.空語句;空語句允許包...

    shleyZ 評論0 收藏0
  • 淺談前端開發(fā)規(guī)范

    結(jié)構(gòu) 樣式 行為分離 模板只包含html文件,模板的書寫順序相應(yīng)的命名規(guī)則 html:語義化css:類名以功能或內(nèi)容命名 樣式復(fù)用 最好少于三級 在沒有必要的情況下避免元素選擇器疊加 Class、ID 使用 屬行的書寫順序 性能 js:避免重復(fù)查找dom 三元操作符電梯if條件語句 二元布爾操作符 樣式寫在一起 變量聲明,保存在一個變量里,避免多次查找dom jQuery鏈?zhǔn)綄懛? 1、獲...

    phodal 評論0 收藏0
  • 淺談前端開發(fā)規(guī)范

    結(jié)構(gòu) 樣式 行為分離 模板只包含html文件,模板的書寫順序相應(yīng)的命名規(guī)則 html:語義化css:類名以功能或內(nèi)容命名 樣式復(fù)用 最好少于三級 在沒有必要的情況下避免元素選擇器疊加 Class、ID 使用 屬行的書寫順序 性能 js:避免重復(fù)查找dom 三元操作符電梯if條件語句 二元布爾操作符 樣式寫在一起 變量聲明,保存在一個變量里,避免多次查找dom jQuery鏈?zhǔn)綄懛? 1、獲...

    Luosunce 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<