java如何消除太多的if else判断?
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判断?相关推荐
- 代码重构----使用java有限状态机来消除太多的if else判断
1. 状态机基本概念 http://zh.wikipedia.org/wiki/%E6%9C%89%E9%99%90%E7%8A%B6%E6%80%81%E6%9C%BA 状态存储关于过去的信息,就是 ...
- java 去掉大量if else_java如何消除太多的if else判断?
1.简介 if判断语句是很多编程语言的重要组成部分.但是,若我们最终编写了大量嵌套的if语句,这将使得我们的代码更加复杂和难以维护. 让我们看看能否使用别的方式来做呢. 设计模式是为了更好的代码重用性 ...
- java.函数参数太多,Java方法参数太多怎么办—Part 2—引入参数对象,javapart
Java方法参数太多怎么办-Part 2-引入参数对象,javapart 目录 自定义类型 引入参数对象 本文是这个系列的第二篇文章,介绍了通过引入参数对象应对参数过多的问题.如果你也希望参与类似的系 ...
- 现在JAVA工程师真是太卷了,招聘要求十条都算少的了
现在JAVA工程师真是太卷了,招聘要求十条都算少的了. 要会各种框架 要会各种设计模式 要会各种缓存和消息机制 要精通各种数据库 要会大数据 要会云计算 要有高并发经验 还要会各种中间件. 首先公司开 ...
- java包间通信,诊断Java代码: 消除包间的耦合关联[Java编程]
赞助商链接 本文"诊断Java代码: 消除包间的耦合关联[Java编程]"是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自 ...
- 成都Java培训机构太多,该怎样选择呢?
Java培训的势头愈发火热,越来越多的人看到了Java培训的前途所在,但是最好的Java培训机构是哪家呢?怎样判断一家Java培训机构的专业性呢?成都传智播客来详细介绍java专业培训机构所具有的特色 ...
- java 正则表达式 判断 日期_怎么在java中利用正则表达式对时间日期进行判断
怎么在java中利用正则表达式对时间日期进行判断 发布时间:2020-12-08 16:18:34 来源:亿速云 阅读:105 作者:Leah 这篇文章给大家介绍怎么在java中利用正则表达式对时间日 ...
- Java生成两个圆判断是否重叠,用java随机画出两个圆,判断它们是不是相交
用java随机画出两个圆,判断它们是否相交 import java.awt.*; import java.util.Random; import javax.swing.*; import javax ...
- 运用c++与easyx图形库实现消灭星星最基本的消除功能、掉落功能以及判断死锁的方式
运用c++与easyx图形库实现消灭星星最基本的消除功能.掉落功能以及判断死锁的方式 写在前面的话 此程序只实现了游戏的小部分内容,没有华丽的外观与消除特效 消灭星星是一款前些年十分流行的手机游戏,玩 ...
最新文章
- signal---高级信号注册函数
- 安徽计算机省一级考试试题,安徽计算机一级考试试题及答案
- iphone定时关机_成都苹果维修点教你iPhone手机死机、关不了机怎么处理?
- 笔记-组织级项目管理与大型项目管理-大型及复杂项目
- 小米和腾讯的.NET笔面试题哪个更难?可自测附答案
- easybcd 支持 windows 10 和 ubuntu 14.04 双系统启动
- 5G手机将不用流量可免费看电视,网友:流量免费,内容付费?
- 学好前端的 6 点建议,企业需要什么样的Web前端人才?
- Python3入门(三)——Python基础语法
- 倒角距离(Chamfer distance)和earth mover‘s diatance
- [导入]Replace函数vbTextCompare不支持日文韩文
- VS2008下编译C++程序,找不到 stdint.h,原因及解决方案
- 每个人都应该了解的HTTPS知识
- SAMBA服务和FTP/sshd 服务讲解
- Jquery实现全选反选和省城市联动效果
- 计算机局域网共享本地安全策略,如何设置局域网共享
- Python之基础语法
- 电流探头的主要指标及应用场合
- 可编程式坐标--单位圆坐标
- 这可是全网EVE安装最完整,最详细的图解,没有之一【安装图解】
热门文章
- Linux面试相关 c程序的运行流程
- android 7 蓝牙版本,[Android]Android什么版本开始支持蓝牙4.2?答案:Android 7.0
- python迷宫问题的所有路径_python——迷宫问题总结
- python运行卡死_快速解决jupyter启动卡死的问题
- linux内核创建ubi,UBI文件系统制作和挂载
- pythonsuper多重继承_小白都能理解的Python多继承
- 笔记本电脑性价比排行2019_办公笔记本电脑排名2019 五款适合办公的笔记本电脑推荐...
- android标尺自定义view,android尺子的自定义view——RulerView详解
- php td内容换行,table单元格内容过多换行显示
- java小程序连接数据库_Java程序连接各种数据库的方法