Java中的大量if else语句的替代方案

91 篇文章 17 订阅
67 篇文章 2 订阅

开发过程中可能会出现大量If else的场景,非常不优雅。

之前写过转载过一篇类似的不错的文章《除代码中的 if-else/switch-case的正确姿势》消除代码中的 if-else/switch-case的正确姿势_明明如月学长的博客-CSDN博客

这里翻译一篇进行补充。

-------------------------------------------------------------------------------------------------------------

1. 简介

大量的if嵌套让代码的复杂性增高而且难以维护。本文将介绍多种解决方案。

2. 案例

下面模拟业务逻辑,根据传入的条件作出不同的处理方式。

我们拿一个计算器类当做案例,有加减乘除四种方法,输出结果是和四种操作有关。

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;
}

随着条件越来越多,复杂性也增高,也越来越难以维护。

3. 重构

3.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 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));
    }

调用

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

新增操作只需要维护操作工厂的operationMap即可。

3.2. 使用枚举

在枚举中定义操作,如下:

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);
}

3.3. 命令模式

定义命令接口

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类,加入执行命令的方法。

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

测试代码

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

3.4. 规则引擎

定义规则接口

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

实现规则引擎

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();
    }
}

定义表达式

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());
}

4. 结论

本文介绍了多种简化if -else 复杂度的方式。

英文原文:How to Replace Many if Statements in Java | Baeldung

其他参考资料:

策略设计模式:策略模式 | 菜鸟教程

命令设计模式:命令模式 | 菜鸟教程

如果觉得本文对你有帮助,欢迎点赞评论,欢迎关注我,我将努力创作更多更好的文章。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

明明如月学长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值