1.简介

if判断语句是很多编程语言的重要组成部分。但是,若我们最终编写了大量嵌套的if语句,这将使得我们的代码更加复杂和难以维护。

让我们看看能否使用别的方式来做呢。

设计模式是为了更好的代码重用性,可读性,可靠性,可维护性,它有六大原则

      1)单一职责原则(Single Responsibility Principle,简称SRP):该原则是针对类来说的,即一个类应该只负责一项职责.
      2)开放--封闭原则(The Open-Closed Principle简称OCP):是说软件实体(类、模块、函数等等)应该可以扩展,但是不可以修改。
      3)依赖倒转原则(Dependence Inversion Principle :针对接口编程,不要对实现编程
      4)里氏代换原则(Liskov Substitution Principle,简称LSP):里氏代换原则,子类型必须能够替换掉他们的父类型
      5)迪米特法则(Law of Demeter):如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用
      6)合成/聚合复用原则(Composition/Aggregation Principle],简称CARP):尽量使用合成/聚合,尽量不使用类继承。合成聚合是“has  a”的关系,而继承是“is  a”的关系。

2.示例

if..else

    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;} else if ("modulo".equals(operator)) {result = a % b;}return result;}

case-switch

    public int calculateUsingSwitch(int a, int b, String operator) {int result = 0;switch (operator) {case "add":result = a + b;break;case "multiply":result = a * b;break;case "divide":result = a / b;break;case "subtract":result = a - b;break;case "modulo":result = a % b;break;default:result = Integer.MIN_VALUE;}return result;}

3.重构

3.1 工厂方式重构

抽象层Operation.java

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

加法实现Addition.java:

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

减法实现Subtraction.java

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

乘法实现Multiplication.java

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

除法实现Division.java

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

求余实现Modulo.java

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

工厂类OperatorFactory.java

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;public class OperatorFactory {static Map<String, Operation> operationMap = new HashMap<>();static {operationMap.put("add", new Addition());operationMap.put("divide", new Division());operationMap.put("multiply", new Multiplication());operationMap.put("subtract", new Subtraction());operationMap.put("modulo", new Modulo());}public static Optional<Operation> getOperation(String operation) {return Optional.ofNullable(operationMap.get(operation));}
}

使用示例

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

3.2 枚举方式重构

枚举实现Operator.java

public enum Operator {ADD {@Overridepublic int apply(int a, int b) {return a + b;}},MULTIPLY {@Overridepublic int apply(int a, int b) {return a * b;}},SUBTRACT {@Overridepublic int apply(int a, int b) {return a - b;}},DIVIDE {@Overridepublic int apply(int a, int b) {return a / b;}},MODULO {@Overridepublic int apply(int a, int b) {return a % b;}};public abstract int apply(int a, int b);
}

封装Operator到Calculator.java

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

使用示例

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

3.3 命令模式

抽象的接口

public interface Command {Integer execute();
}

实现类

package com.baeldung.reducingIfElse;public class AddCommand implements Command {private int a;private int b;public AddCommand(int a, int b) {this.a = a;this.b = b;}@Overridepublic Integer execute() {return a + b;}
}

其它略

包装

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

测试demo

@Test
public void whenCalculateUsingCommand_thenReturnCorrectResult() {Calculator calculator = new Calculator();int result = calculator.calculate(new AddCommand(3, 7));assertEquals(10, result);
}

4.规则引擎重构

抽象规则

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

实现规则AddRule.java 其它略

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

其中:返回结果

public class Result {int value;public Result(int value) {this.value = value;}public int getValue() {return value;}
}

表达式

public class Expression {private Integer x;private Integer y;private Operator operator;public Expression(Integer x, Integer y, Operator operator) {this.x = x;this.y = y;this.operator = operator;}public Integer getX() {return x;}public Integer getY() {return y;}public Operator getOperator() {return operator;}
}

规则引擎RuleEngine.java

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;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();}
}

测试demo

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

4.比较

重构方式 SRP OCP DIP LSP LD CARP
IF/ELSE N N N N N N
工厂方法 Y Y Y Y Y Y
枚举方法 N Y Y Y Y Y
命令模式 Y Y Y Y Y Y
规则引擎 Y Y Y Y Y Y

5.小结

 为了更好的代码重用性,可读性,可靠性,可维护性,我们会尝试将IF/ELSE或者case-switch进行改造,使用工厂方法,枚举方法,命令模式,规则引擎方式不同方法进行尝试,最后使用设计模式的六大原则对代码进行评估。

参考资料

【1】https://www.cnblogs.com/davidwang456/p/3641369.html

【2】https://www.baeldung.com/java-replace-if-statements

转载于:https://www.cnblogs.com/davidwang456/p/10831546.html

java如何消除太多的if else判断?相关推荐

  1. 代码重构----使用java有限状态机来消除太多的if else判断

    1. 状态机基本概念 http://zh.wikipedia.org/wiki/%E6%9C%89%E9%99%90%E7%8A%B6%E6%80%81%E6%9C%BA 状态存储关于过去的信息,就是 ...

  2. java 去掉大量if else_java如何消除太多的if else判断?

    1.简介 if判断语句是很多编程语言的重要组成部分.但是,若我们最终编写了大量嵌套的if语句,这将使得我们的代码更加复杂和难以维护. 让我们看看能否使用别的方式来做呢. 设计模式是为了更好的代码重用性 ...

  3. java.函数参数太多,Java方法参数太多怎么办—Part 2—引入参数对象,javapart

    Java方法参数太多怎么办-Part 2-引入参数对象,javapart 目录 自定义类型 引入参数对象 本文是这个系列的第二篇文章,介绍了通过引入参数对象应对参数过多的问题.如果你也希望参与类似的系 ...

  4. 现在JAVA工程师真是太卷了,招聘要求十条都算少的了

    现在JAVA工程师真是太卷了,招聘要求十条都算少的了. 要会各种框架 要会各种设计模式 要会各种缓存和消息机制 要精通各种数据库 要会大数据 要会云计算 要有高并发经验 还要会各种中间件. 首先公司开 ...

  5. java包间通信,诊断Java代码: 消除包间的耦合关联[Java编程]

    赞助商链接 本文"诊断Java代码: 消除包间的耦合关联[Java编程]"是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自 ...

  6. 成都Java培训机构太多,该怎样选择呢?

    Java培训的势头愈发火热,越来越多的人看到了Java培训的前途所在,但是最好的Java培训机构是哪家呢?怎样判断一家Java培训机构的专业性呢?成都传智播客来详细介绍java专业培训机构所具有的特色 ...

  7. java 正则表达式 判断 日期_怎么在java中利用正则表达式对时间日期进行判断

    怎么在java中利用正则表达式对时间日期进行判断 发布时间:2020-12-08 16:18:34 来源:亿速云 阅读:105 作者:Leah 这篇文章给大家介绍怎么在java中利用正则表达式对时间日 ...

  8. Java生成两个圆判断是否重叠,用java随机画出两个圆,判断它们是不是相交

    用java随机画出两个圆,判断它们是否相交 import java.awt.*; import java.util.Random; import javax.swing.*; import javax ...

  9. 运用c++与easyx图形库实现消灭星星最基本的消除功能、掉落功能以及判断死锁的方式

    运用c++与easyx图形库实现消灭星星最基本的消除功能.掉落功能以及判断死锁的方式 写在前面的话 此程序只实现了游戏的小部分内容,没有华丽的外观与消除特效 消灭星星是一款前些年十分流行的手机游戏,玩 ...

最新文章

  1. signal---高级信号注册函数
  2. 安徽计算机省一级考试试题,安徽计算机一级考试试题及答案
  3. iphone定时关机_成都苹果维修点教你iPhone手机死机、关不了机怎么处理?
  4. 笔记-组织级项目管理与大型项目管理-大型及复杂项目
  5. 小米和腾讯的.NET笔面试题哪个更难?可自测附答案
  6. easybcd 支持 windows 10 和 ubuntu 14.04 双系统启动
  7. 5G手机将不用流量可免费看电视,网友:流量免费,内容付费?
  8. 学好前端的 6 点建议,企业需要什么样的Web前端人才?
  9. Python3入门(三)——Python基础语法
  10. 倒角距离(Chamfer distance)和earth mover‘s diatance
  11. [导入]Replace函数vbTextCompare不支持日文韩文
  12. VS2008下编译C++程序,找不到 stdint.h,原因及解决方案
  13. 每个人都应该了解的HTTPS知识
  14. SAMBA服务和FTP/sshd 服务讲解
  15. Jquery实现全选反选和省城市联动效果
  16. 计算机局域网共享本地安全策略,如何设置局域网共享
  17. Python之基础语法
  18. 电流探头的主要指标及应用场合
  19. 可编程式坐标--单位圆坐标
  20. 这可是全网EVE安装最完整,最详细的图解,没有之一【安装图解】

热门文章

  1. Linux面试相关 c程序的运行流程
  2. android 7 蓝牙版本,[Android]Android什么版本开始支持蓝牙4.2?答案:Android 7.0
  3. python迷宫问题的所有路径_python——迷宫问题总结
  4. python运行卡死_快速解决jupyter启动卡死的问题
  5. linux内核创建ubi,UBI文件系统制作和挂载
  6. pythonsuper多重继承_小白都能理解的Python多继承
  7. 笔记本电脑性价比排行2019_办公笔记本电脑排名2019 五款适合办公的笔记本电脑推荐...
  8. android标尺自定义view,android尺子的自定义view——RulerView详解
  9. php td内容换行,table单元格内容过多换行显示
  10. java小程序连接数据库_Java程序连接各种数据库的方法