最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java if-else 多重嵌套的優(yōu)化方式

 更新時(shí)間:2022年02月15日 15:16:46   作者:談?wù)?974  
這篇文章主要介紹了Java if-else 多重嵌套的優(yōu)化方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

if-else多重嵌套的優(yōu)化

1. if-else 多重嵌套的問(wèn)題

項(xiàng)目重構(gòu)發(fā)現(xiàn)代碼中存在類(lèi)似以下的三重 if-else 嵌套代碼,其中變量 a、b、c有三種可能的取值,組合起來(lái)共有27 個(gè)分支,這還沒(méi)有算上對(duì)各個(gè)變量進(jìn)行合法性校驗(yàn)失敗的分支。

如此繁雜瑣碎的代碼閱讀起來(lái)有多費(fèi)勁可想而知,而條件判斷太多對(duì)理解業(yè)務(wù)邏輯也是個(gè)問(wèn)題,更不用提之后的擴(kuò)展維護(hù)

if (a == 1) {
    if (b == 1) {
        if (c == 1) {
        } else if (c == 2) {
        } else if (c == 3) {
        } else {
        }
    } else if (b == 2) {
    }
    ......        
} else if (a == 2) {
  ......
}       

2. 解決方案

條件判斷嵌套過(guò)多的害處毋庸多言,仔細(xì)思索后大致整理了優(yōu)化思路,首要點(diǎn)是將多重條件判斷進(jìn)行整合。如以上例子中對(duì) 3 個(gè)變量的取值逐一判斷來(lái)確定一條分支其實(shí)可以優(yōu)化為以 3 個(gè)變量聚合為一個(gè)條件進(jìn)行分支確定,這樣分支數(shù)并不會(huì)減少,但是對(duì)條件的判斷必然是更為清晰的

2.1 使用Map緩存

基于以上例子,變量 a、b、c都是整數(shù)類(lèi)型的數(shù)據(jù),則可以考慮將其合并為一個(gè)String 數(shù)據(jù),以字符串"111" 來(lái)表示 a=1, b=1, c=1 的條件,這樣可以用一個(gè) Map 結(jié)構(gòu)來(lái)存儲(chǔ)對(duì)應(yīng)操作標(biāo)識(shí),從而實(shí)現(xiàn)策略切換。這種方式通常會(huì)另外新建一個(gè)工具類(lèi),通過(guò)工具類(lèi)來(lái)獲取對(duì)應(yīng)條件的結(jié)果

public static Map<String, MatchVerifyResultDTO> getInstance() {
        if (upCreditMap.isEmpty()) {
            MatchVerifyResultDTO invalidResult = new MatchVerifyResultDTO(false,
                    MatchVerifyEnum.MVC_UP_CREDIT_ERR.getCode());
            MatchVerifyResultDTO validResult = new MatchVerifyResultDTO(true, MatchVerifyEnum.MVC_PASS.getCode());
            upCreditMap.put("111", invalidResult);
            upCreditMap.put("112", validResult);
            upCreditMap.put("113", validResult);
          ......
        }
        return upCreditMap;
    }

2.2 switch 簡(jiǎn)化條件

如果不準(zhǔn)備新建工具類(lèi)來(lái)實(shí)現(xiàn)條件簡(jiǎn)化,也可以采用 switch結(jié)構(gòu)。不過(guò)不管何種方式,核心思想是不變的,即采用整體數(shù)據(jù)來(lái)消弭小的差異判斷,此處依然將變量 a、b、c合并為一個(gè)String 特征條件

switch(attribute) {
     case "111":
     case "112":
         handleTargetMessage();
         break;         
     ......     
     default:
         log.error("Not supported attribute!")
           break;
}

多個(gè)ifelse語(yǔ)句的替代設(shè)計(jì)

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

接下來(lái),讓我們探索如何簡(jiǎn)化代碼的中的ifelse語(yǔ)句寫(xiě)法。

案例研究

我們經(jīng)常遇到涉及很多條件的業(yè)務(wù)邏輯,并且每個(gè)邏輯都需要不同的處理方式。以Calculator類(lèi)為例。我們將有一個(gè)方法,它接受兩個(gè)數(shù)字和一個(gè)運(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語(yǔ)句來(lái)實(shí)現(xiàn)它:

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

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

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

重構(gòu)

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

工廠模式

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

對(duì)于我們的示例,讓我們定義一個(gè)具有單個(gè)apply方法的Operation接口:

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

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

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

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

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

現(xiàn)在,在Calculator類(lèi)中,我們可以查詢工廠以獲取相關(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);
}

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

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

使用枚舉

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

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

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

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

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

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

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

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

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

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

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

命令模式

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

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

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

public interface Command {
? ? Integer execute();
}

接下來(lái),讓我們實(shí)現(xiàn)一個(gè)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;
? ? }
}

最后,讓我們?cè)贑alculator中引入一個(gè)接受并執(zhí)行Command的新方法:

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

接下來(lái),我們可以通過(guò)實(shí)例化AddCommand調(diào)用計(jì)算并將其發(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)我們最終編寫(xiě)大量嵌套if語(yǔ)句時(shí),每個(gè)條件都描述了一個(gè)業(yè)務(wù)規(guī)則,必須對(duì)其進(jìn)行評(píng)估才能處理正確的邏輯。規(guī)則引擎從主代碼中獲取了這種復(fù)雜性。一個(gè)RuleEngine評(píng)估規(guī)則和返回基于輸入的結(jié)果。

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

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

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

public class RuleEngine {
? ? private static List<Rule> 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接受一個(gè)表達(dá)對(duì)象,并返回結(jié)果?,F(xiàn)在,讓我們將Expression類(lèi)設(shè)計(jì)為一組包含兩個(gè)Integer對(duì)象的Operator,它將被應(yīng)用:

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

最后讓我們定義一個(gè)自定義的AddRule類(lèi),該類(lèi)僅在指定ADD操作時(shí)進(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é)

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

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • MyBatisPlus查詢投影與查詢條件詳細(xì)講解

    MyBatisPlus查詢投影與查詢條件詳細(xì)講解

    這篇文章主要介紹了MyBatisPlus DQL編程控制中的查詢投影、查詢條件,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • Windows編寫(xiě)jar啟動(dòng)腳本和關(guān)閉腳本的操作方法

    Windows編寫(xiě)jar啟動(dòng)腳本和關(guān)閉腳本的操作方法

    腳本文件,通常放入/bin目錄下,編寫(xiě)啟動(dòng)腳本需要保證能夠識(shí)別到對(duì)應(yīng)的jar文件,其次需要保證能夠識(shí)別到/config中的配置文件信息,這篇文章主要介紹了Windows編寫(xiě)jar啟動(dòng)腳本和關(guān)閉腳本的操作方法,需要的朋友可以參考下
    2022-12-12
  • MyBatis-Plus與Druid結(jié)合Dynamic-datasource實(shí)現(xiàn)多數(shù)據(jù)源操作數(shù)據(jù)庫(kù)的示例

    MyBatis-Plus與Druid結(jié)合Dynamic-datasource實(shí)現(xiàn)多數(shù)據(jù)源操作數(shù)據(jù)庫(kù)的示例

    Dynamic-DataSource 可以和絕大多是連接層插件搭配使用,比如:mybatis,mybatis-plus,hibernate等,本文就來(lái)介紹一下MyBatis-Plus與Druid結(jié)合Dynamic-datasource實(shí)現(xiàn)多數(shù)據(jù)源操作數(shù)據(jù)庫(kù)的示例,感興趣的可以了解一下
    2023-10-10
  • 深入理解Spring的事務(wù)傳播行為

    深入理解Spring的事務(wù)傳播行為

    spring特有的事務(wù)傳播行為,spring支持7種事務(wù)傳播行為,確定客戶端和被調(diào)用端的事務(wù)邊界(說(shuō)得通俗一點(diǎn)就是多個(gè)具有事務(wù)控制的service的相互調(diào)用時(shí)所形成的復(fù)雜的事務(wù)邊界控制),這篇文章主要給大家介紹了關(guān)于Spring事務(wù)傳播行為的相關(guān)資料,需要的朋友可以參考下。
    2018-02-02
  • 詳解Java中的內(nèi)存屏障

    詳解Java中的內(nèi)存屏障

    這篇文章主要介紹了Java中的內(nèi)存屏障的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下
    2021-05-05
  • Java生成條形碼code128(親測(cè)有效)

    Java生成條形碼code128(親測(cè)有效)

    這篇文章主要介紹了Java生成條形碼code128,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • 一種新的日期處理方式之JavaScript Temporal API

    一種新的日期處理方式之JavaScript Temporal API

    JavaScript Temporal API是一種為Web開(kāi)發(fā)人員提供了一種新的處理日期和時(shí)間數(shù)據(jù)類(lèi)型的方式。它的目的是使操作日期和時(shí)間更加簡(jiǎn)單和可靠,而且不用擔(dān)心歷史時(shí)區(qū)問(wèn)題或全球化協(xié)調(diào)時(shí)間(UTC)之類(lèi)的問(wèn)題,感興趣的同學(xué)可以參考閱讀
    2023-05-05
  • 詳解SpringIOC容器中bean的作用范圍和生命周期

    詳解SpringIOC容器中bean的作用范圍和生命周期

    這篇文章主要介紹了SpringIOC容器中bean的作用范圍和生命周期,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-02-02
  • Java中的MapStruct實(shí)現(xiàn)詳解

    Java中的MapStruct實(shí)現(xiàn)詳解

    這篇文章主要介紹了Java中的MapStruct實(shí)現(xiàn)詳解,MapStruct 是一個(gè)代碼生成器,它基于約定優(yōu)先于配置的方法大大簡(jiǎn)化了 JavaBean 類(lèi)型之間映射的實(shí)現(xiàn),生成的映射代碼使用普通方法調(diào)用,需要的朋友可以參考下
    2023-11-11
  • 基于SpringBoot實(shí)現(xiàn)自動(dòng)裝配返回屬性的設(shè)計(jì)思路

    基于SpringBoot實(shí)現(xiàn)自動(dòng)裝配返回屬性的設(shè)計(jì)思路

    這篇文章主要介紹了基于SpringBoot實(shí)現(xiàn)自動(dòng)裝配返回屬性,這里涉及到的技術(shù)知識(shí)點(diǎn)有注解解析器,為什么用ResponseBodyAdvice這里解析?不在Filter,Interceptors,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2022-03-03

最新評(píng)論

河西区| 抚顺县| 河津市| 鹤庆县| 武平县| 来宾市| 达孜县| 科技| 西充县| 西城区| 上饶市| 彭州市| 班戈县| 罗定市| 新郑市| 宜春市| 泸定县| 新安县| 长乐市| 睢宁县| 唐海县| 库尔勒市| 汉中市| 察隅县| 芦山县| 无为县| 和硕县| 博乐市| 珠海市| 政和县| 杭锦旗| 巴青县| 交城县| 通渭县| 措美县| 宁津县| 南木林县| 绥棱县| 连州市| 昌江| 泸州市|