• 优雅代码之消除if-else判断


    臃肿示例

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

    重构

    工厂方式重构

    1. 抽象接口 Operation.java

     

    public interface Operation {
     int apply(int a, int b);
    }
    1. 加法实现 Addition.java:
    public class Addition implements Operation {
     @Override
     public int apply(int a, int b) {
     return a + b;
     }
    }
    1. 减法实现 Subtraction.java
    public class Subtraction implements Operation {
     @Override public int apply(int a, int b) {
     return a - b;
     }
    }
    1. 乘法实现 Multiplication.java
    public class Multiplication implements Operation {
     @Override public int apply(int a, int b) {
     return a*b;
     }
    }
    1. 除法实现 Division.java
    public class Division implements Operation {
     @Override public int apply(int a, int b) {
     return a / b;
     }
    }
    1. 求余实现 Modulo.java
    public class Modulo implements Operation {
     @Override public int apply(int a, int b) {
     return a % b;
     }
    }
    1. 工厂类 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));
     }
    }
    1. 使用示例
    public int calculateUsingFactory(int a, int b, String operator) {
     Operation targetOperation = OperatorFactory
     .getOperation(operator)
     .orElseThrow(() -> new IllegalArgumentException("Invalid Operator"));
     return targetOperation.apply(a, b);
    } 

    枚举方式重构

    1. 枚举实现Operator.java
    public enum Operator {
     ADD {
     @Override
     public int apply(int a, int b) {
     return a + b;
     }
     },
     MULTIPLY {
     @Override
     public int apply(int a, int b) {
     return a * b;
     }
     },
     SUBTRACT {
     @Override
     public int apply(int a, int b) {
     return a - b;
     }
     },
     DIVIDE {
     @Override
     public int apply(int a, int b) {
     return a / b;
     }
     },
     MODULO {
     @Override
     public int apply(int a, int b) {
     return a % b;
     }
     };
     public abstract int apply(int a, int b);
    }
    1. 封装Operator到Calculator.java
     public int calculate(int a, int b, Operator operator) {
     return operator.apply(a, b);
     }
    1. 使用示例
    @Test
    public void whenCalculateUsingEnumOperator_thenReturnCorrectResult() {
     Calculator calculator = new Calculator();
     int result = calculator.calculate(3, 4, Operator.valueOf("ADD"));
     assertEquals(7, result);
    }

    命令模式

    1. 抽象的接口
    public interface Command {
     Integer execute();
    }
    1. 实现类
    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;
     }
     @Override
     public Integer execute() {
     return a + b;
     }
    }
    1. 包装
     public int calculate(Command command) {
     return command.execute();
     }
    1. 测试demo
    @Test
    public void whenCalculateUsingCommand_thenReturnCorrectResult() {
     Calculator calculator = new Calculator();
     int result = calculator.calculate(new AddCommand(3, 7));
     assertEquals(10, result);
    }

    规则引擎重构

    1. 抽象规则
    public interface Rule {
     boolean evaluate(Expression expression);
     Result getResult();
    }
    1. 实现规则AddRule.java
    public class AddRule implements Rule {
     private int result;
     @Override
     public boolean evaluate(Expression expression) {
     boolean evalResult = false;
     if (expression.getOperator() == Operator.ADD) {
     this.result = expression.getX() + expression.getY();
     evalResult = true;
     }
     return evalResult;
     }
     @Override
     public 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();
     }
    }
    1. 测试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());
    }

    小结

    为了更好的代码重用性,可读性,可靠性,可维护性,我们会尝试将IF/ELSE或者case-switch进行改造,使用工厂方法,枚举方法,命令模式,规则引擎方式不同方法进行尝试,最后使用设计模式的六大原则对代码进行评估。

  • 相关阅读:
    localStorage保存账号密码
    作品第二课----简易年历
    作品第二课----滚动列表
    自己遇到的冒泡事件
    Oct 20th-绿叶学习网站总结
    Sep 30th-JavaScript的数组方法总结
    Sep 8th -css sprite
    前端知识体系【转】
    July 27th
    第一节 简单的jsp实例
  • 原文地址:https://www.cnblogs.com/zhouheblog/p/11308883.html
Copyright © 2020-2023  润新知