首页 > > > 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

publicintcalculate(inta,int b, String operator) {
intresult = Integer.MIN_VALUE;
if("add".equals(operator)) {
result = a + b;
} elseif("multiply".equals(operator)) {
result = a * b;
} elseif("divide".equals(operator)) {
result = a / b;
} elseif("subtract".equals(operator)) {
result = a - b;
} elseif("modulo".equals(operator)) {
result = a % b;
}
return result;
}

case-switch

publicintcalculateUsingSwitch(inta,int b, String operator) {
intresult = 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
publicinterface Operation {
intapply(inta,int b);
}
加法实现Addition.java:
publicclassAdditionimplements Operation {
@Override
publicintapply(inta,int b) {
returna + b;
}
}
减法实现Subtraction.java
publicclassSubtractionimplements Operation {
@Override publicintapply(inta,int b) {
returna - b;
}
}
乘法实现Multiplication.java
publicclassMultiplicationimplements Operation {
@Override publicintapply(inta,int b) {
returna*b;
}
}
除法实现Division.java
publicclassDivisionimplements Operation {
@Override publicintapply(inta,int b) {
returna / b;
}
}
求余实现Modulo.java
publicclassModuloimplements Operation {
@Override publicintapply(inta,int b) {
returna % b;
}
}
工厂类OperatorFactory.java

import java.util.HashMap;import java.util.Map;import java.util.Optional;publicclass OperatorFactory {
staticMap
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());
}
publicstaticOptional
return Optional.ofNullable(operationMap.get(operation));
}
}

使用示例
publicintcalculateUsingFactory(inta,int b, String operator) {
Operation targetOperation = OperatorFactory
.getOperation(operator)
.orElseThrow(() ->newIllegalArgumentException("Invalid Operator"));
return targetOperation.apply(a, b);
}
3.2 枚举方式重构
枚举实现Operator.java

publicenum Operator {
ADD {
@Override
publicintapply(inta,int b) {
returna + b;
}
},
MULTIPLY {
@Override
publicintapply(inta,int b) {
returna * b;
}
},
SUBTRACT {
@Override
publicintapply(inta,int b) {
returna - b;
}
},
DIVIDE {
@Override
publicintapply(inta,int b) {
returna / b;
}
},
MODULO {
@Override
publicintapply(inta,int b) {
returna % b;
}
};
publicabstractintapply(inta,int b);
}

封装Operator到Calculator.java
publicintcalculate(inta,int b, Operator operator) {
return operator.apply(a, b);
}
使用示例
@Testpublicvoid whenCalculateUsingEnumOperator_thenReturnCorrectResult() {
Calculator calculator =new Calculator();
intresult = calculator.calculate(3, 4, Operator.valueOf("ADD"));
assertEquals(7, result);
}
3.3 命令模式
抽象的接口
publicinterface Command {
Integer execute();
}
实现类

package com.baeldung.reducingIfElse;publicclassAddCommandimplements Command {
privateint a;
privateint b;
publicAddCommand(inta,int b) {
this.a = a;
this.b = b;
}
@Override
public Integer execute() {
returna + b;
}
}

其它略
包装
publicint calculate(Command command) {
return command.execute();
}
测试demo
@Testpublicvoid whenCalculateUsingCommand_thenReturnCorrectResult() {
Calculator calculator =new Calculator();
intresult = calculator.calculate(newAddCommand(3, 7));
assertEquals(10, result);
}
4.规则引擎重构
抽象规则
publicinterface Rule {
boolean evaluate(Expression expression);
Result getResult();
}
实现规则AddRule.java 其它略

publicclassAddRuleimplements Rule {
privateint result;
@Override
publicboolean evaluate(Expression expression) {
booleanevalResult =false;
if(expression.getOperator() == Operator.ADD) {
this.result = expression.getX() + expression.getY();
evalResult =true;
}
return evalResult;
}
@Override
public Result getResult() {
returnnew Result(result);
}
}

其中:返回结果

publicclass Result {
int value;
publicResult(int value) {
this.value = value;
}
publicint getValue() {
return value;
}
}

表达式

publicclass 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;publicclass RuleEngine {
privatestaticList
static {
rules.add(new AddRule());
}
public Result process(Expression expression) {
Rule rule = rules.stream()
.filter(r -> r.evaluate(expression))
.findFirst()
.orElseThrow(() ->newIllegalArgumentException("Expression does not matches any Rule"));
return rule.getResult();
}
}

测试demo

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

4.比较
重构方式SRPOCPDIPLSPLDCARP
IF/ELSENNNNNN
工厂方法YYYYYY
枚举方法NYYYYY
命令模式YYYYYY
规则引擎YYYYYY
5.小结
为了更好的代码重用性,可读性,可靠性,可维护性,我们会尝试将IF/ELSE或者case-switch进行改造,使用工厂方法,枚举方法,命令模式,规则引擎方式不同方法进行尝试,最后使用设计模式的六大原则对代码进行评估。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

publicintcalculate(inta,int b, String operator) {
intresult = Integer.MIN_VALUE;
if("add".equals(operator)) {
result = a + b;
} elseif("multiply".equals(operator)) {
result = a * b;
} elseif("divide".equals(operator)) {
result = a / b;
} elseif("subtract".equals(operator)) {
result = a - b;
} elseif("modulo".equals(operator)) {
result = a % b;
}
return result;
}

case-switch

publicintcalculateUsingSwitch(inta,int b, String operator) {
intresult = 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
publicinterface Operation {
intapply(inta,int b);
}
加法实现Addition.java:
publicclassAdditionimplements Operation {
@Override
publicintapply(inta,int b) {
returna + b;
}
}
减法实现Subtraction.java
publicclassSubtractionimplements Operation {
@Override publicintapply(inta,int b) {
returna - b;
}
}
乘法实现Multiplication.java
publicclassMultiplicationimplements Operation {
@Override publicintapply(inta,int b) {
returna*b;
}
}
除法实现Division.java
publicclassDivisionimplements Operation {
@Override publicintapply(inta,int b) {
returna / b;
}
}
求余实现Modulo.java
publicclassModuloimplements Operation {
@Override publicintapply(inta,int b) {
returna % b;
}
}
工厂类OperatorFactory.java

import java.util.HashMap;import java.util.Map;import java.util.Optional;publicclass OperatorFactory {
staticMap
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());
}
publicstaticOptional
return Optional.ofNullable(operationMap.get(operation));
}
}

使用示例
publicintcalculateUsingFactory(inta,int b, String operator) {
Operation targetOperation = OperatorFactory
.getOperation(operator)
.orElseThrow(() ->newIllegalArgumentException("Invalid Operator"));
return targetOperation.apply(a, b);
}
3.2 枚举方式重构
枚举实现Operator.java

publicenum Operator {
ADD {
@Override
publicintapply(inta,int b) {
returna + b;
}
},
MULTIPLY {
@Override
publicintapply(inta,int b) {
returna * b;
}
},
SUBTRACT {
@Override
publicintapply(inta,int b) {
returna - b;
}
},
DIVIDE {
@Override
publicintapply(inta,int b) {
returna / b;
}
},
MODULO {
@Override
publicintapply(inta,int b) {
returna % b;
}
};
publicabstractintapply(inta,int b);
}

封装Operator到Calculator.java
publicintcalculate(inta,int b, Operator operator) {
return operator.apply(a, b);
}
使用示例
@Testpublicvoid whenCalculateUsingEnumOperator_thenReturnCorrectResult() {
Calculator calculator =new Calculator();
intresult = calculator.calculate(3, 4, Operator.valueOf("ADD"));
assertEquals(7, result);
}
3.3 命令模式
抽象的接口
publicinterface Command {
Integer execute();
}
实现类

package com.baeldung.reducingIfElse;publicclassAddCommandimplements Command {
privateint a;
privateint b;
publicAddCommand(inta,int b) {
this.a = a;
this.b = b;
}
@Override
public Integer execute() {
returna + b;
}
}

其它略
包装
publicint calculate(Command command) {
return command.execute();
}
测试demo
@Testpublicvoid whenCalculateUsingCommand_thenReturnCorrectResult() {
Calculator calculator =new Calculator();
intresult = calculator.calculate(newAddCommand(3, 7));
assertEquals(10, result);
}
4.规则引擎重构
抽象规则
publicinterface Rule {
boolean evaluate(Expression expression);
Result getResult();
}
实现规则AddRule.java 其它略

publicclassAddRuleimplements Rule {
privateint result;
@Override
publicboolean evaluate(Expression expression) {
booleanevalResult =false;
if(expression.getOperator() == Operator.ADD) {
this.result = expression.getX() + expression.getY();
evalResult =true;
}
return evalResult;
}
@Override
public Result getResult() {
returnnew Result(result);
}
}

其中:返回结果

publicclass Result {
int value;
publicResult(int value) {
this.value = value;
}
publicint getValue() {
return value;
}
}

表达式

publicclass 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;publicclass RuleEngine {
privatestaticList
static {
rules.add(new AddRule());
}
public Result process(Expression expression) {
Rule rule = rules.stream()
.filter(r -> r.evaluate(expression))
.findFirst()
.orElseThrow(() ->newIllegalArgumentException("Expression does not matches any Rule"));
return rule.getResult();
}
}

测试demo

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

4.比较
重构方式SRPOCPDIPLSPLDCARP
IF/ELSENNNNNN
工厂方法YYYYYY
枚举方法NYYYYY
命令模式YYYYYY
规则引擎YYYYYY
5.小结
为了更好的代码重用性,可读性,可靠性,可维护性,我们会尝试将IF/ELSE或者case-switch进行改造,使用工厂方法,枚举方法,命令模式,规则引擎方式不同方法进行尝试,最后使用设计模式的六大原则对代码进行评估。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/2730/viewspace-3121119/ ,如需转载,请注明出处,否则将追究法律责任。