专栏首页攻城狮的那点事Java中大量if...else语句的消除替代方案

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

在我们平时的开发过程中,经常可能会出现大量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;
    }
}
然后通过操作工厂提供操作

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、命令模式

定义命令接口。

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

4、规则引擎

定义规则接口

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

本文分享自微信公众号 - 攻城狮的那点事(gh_e40249fc5212)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-12-24

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • SpringCloud微服务项目实战 - 缓存详解及高效缓存接入

    缓存,已经是现在系统中必不可少的内容,如何使用好缓存,对系统的性能和效率至关重要,这里我就来分析一下使用缓存的正确姿势吧。

    攻城狮的那点事
  • MySQL最全的重要知识点都在这里

    MySQL 是一种关系型数据库,在Java企业级开发中非常常用,因为 MySQL 是开源免费的,并且方便扩展。阿里巴巴数据库系统也大量用到了 MySQL,因此它...

    攻城狮的那点事
  • 超全 | 七大排序算法图文详解

    原文:https://www.jianshu.com/p/876931436177

    攻城狮的那点事
  • Java中多个ifelse语句的替代设计

    ifelse是任何编程语言的重要组成部分。但是我们编写了大量嵌套的if语句,这使得我们的代码更加复杂和难以维护。

    王知无
  • Excel Sheet Column Number

  • Java-回调/Callback

    版权声明: ...

    Fisherman渔夫
  • 优化 Java 中的多态代码

    Oracle的Java是一个门快速的语言,有时候它可以和C++一样快。编写Java代码时,我们通常使用接口、继承或者包装类(wrapper class)来实现多...

    用户1257393
  • Spring - AOP(10)

    使用动态代理解决上述问题 代理设计模式的原理:使用一个代理将对象包装起来,然后用该代理对象取代原始对象,任何对原始对象的调用都要通过代理,代理对象决定是否以及...

    桑鱼
  • 一个可以拖动的自定义Gridview代码

    这个可以拖动的gridview继承于gridview,所以,用法和gridview一样, 代码如下: public class DragGridView ext...

    xiangzhihong
  • dsu on tree入门

    说起来我跟这个算法好像还有很深的渊源呢qwq。当时在学业水平考试的考场上,题目都做完了不会做,于是开始xjb出题。突然我想到这么一个题

    attack

扫码关注云+社区

领取腾讯云代金券