在我们平时的开发过程中,经常可能会出现大量If else的场景,代码显的很臃肿,非常不优雅。那我们又没有办法处理呢?
针对大量的if嵌套让代码的复杂性增高而且难以维护。本文将介绍多种解决方案。
下面模拟业务逻辑,根据传入的条件作出不同的处理方式。
拿一个计算器类当做案例,有加减乘除四种方法,输出结果和四种操作有关。
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来实现。
public int calculateUsingSwitch(int a, int b, String operator) {
switch (operator) {
case "add":
result = a + b;
break;
// other cases
}
return result;
}
随着条件越来越多,复杂性也增高,也越来越难以维护。
1、工厂类
我们将操作进行抽象给出一个操作接口
public interface Operation {
int apply(int a, int b);
}
然后实现加减乘除四个方法
public class Addition implements Operation {
@Override
public int apply(int a, int b) {
return a + b;
}
}
然后通过操作工厂提供操作
在枚举中定义操作,如下:
public enum Operator {
ADD, MULTIPLY, SUBTRACT, DIVIDE
}
然而不同的操作对应的逻辑不一样,我们编写抽象方法
ADD {
@Override
public int apply(int a, int b) {
return a + b;
}
},
// other operators
public abstract int apply(int a, int b);
调用时直接传入枚举值
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);
}
定义命令接口。
public interface Command {
Integer execute();
}
实现加法
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类,加入执行命令的方法。
测试代码
@Test
public void whenCalculateUsingCommand_thenReturnCorrectResult() {
Calculator calculator = new Calculator();
int result = calculator.calculate(new AddCommand(3, 7));
assertEquals(10, result);
}
定义规则接口
public interface Rule {
boolean evaluate(Expression expression);
Result getResult();
}
实现规则引擎
public class Expression {
private Integer x;
private Integer y;
private Operator operator;
}
定义加法规则
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;
}
}
给规则引擎传入表达式来调用
@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());
}
总结
虽然说常见的代码中if...else不可避免,但滥用 if...else 会对代码的可读性、可维护性造成很大伤害。因此,使用好 if...else,让代码清爽对于你的项目长远考虑有十分重要的意义。
英文原文:https://www.baeldung.com/java-replace-if-statements 其他参考资料: 策略设计模式:http://www.runoob.com/design-pattern/strategy-pattern.html 命令设计模式:http://www.runoob.com/design-pattern/command-pattern.html