1、简介

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

2、案例

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

public static boolean consume(PurchaseOrderMessageBody purchaseOrder) {
    PurchaseTypeEnum purchaseTypeEnum = PurchaseTypeEnum.getPurchaseTypeEnumByName(purchaseOrder.getOrderType());
    if ("XSD_PC".equals(purchaseTypeEnum.toString())) {
        CreatePurchaseHandler.handler(purchaseOrder);
    } else if ("ZYCS".equals(purchaseTypeEnum.toString())) {
        CreatePurchaseHandler.handler(purchaseOrder);
    }
    .....
    else {
        PurchaseFinishHandler.handler(purchaseOrder);
    }
}

当然也可以用switch来实现

public static boolean consume(PurchaseOrderMessageBody purchaseOrder) {
    PurchaseTypeEnum purchaseTypeEnum = PurchaseTypeEnum.getPurchaseTypeEnumByName(purchaseOrder.getOrderType());
    switch (purchaseTypeEnum) {
        case XSD_PC:
        case ZYCS:
            return CreatePurchaseHandler.handler(purchaseOrder);
        default:
            return PurchaseFinishHandler.handler(purchaseOrder);
    }
}

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

3、重构

3.1.工厂类

我们将操作进行抽象给出一个操作接口

public interface PurchaseTypeBasic {
    boolean purchaseHandler (PurchaseOrderMessageBody purchaseOrder);
}

然后实现创建和完成的方法

public class CreatePurchaseHandler implements PurchaseTypeBasic {
    public boolean purchaseHandler(PurchaseOrderMessageBody purchaseOrder) {
        System.out.println("创建采购履约单");
        return true;
    }
}
public class PurchaseFinishHandler implements PurchaseTypeBasic {
    public boolean purchaseHandler(PurchaseOrderMessageBody purchaseOrder) {
        System.out.println("通知采购履约完成");
        return true;
    }
}

然后通过操作工厂提供操作

public class OperatePurchaseTypeBasic {
    static Map<String, PurchaseTypeBasic> operationMap = new HashMap<>();
    static {
        operationMap.put("XSD_PC", new CreatePurchaseHandler());
        operationMap.put("TRIANGULAR", new PurchaseFinishHandler());
    }
    public static Optional<PurchaseTypeBasic> getOperation(String operator) {
        return Optional.ofNullable(operationMap.get(operator));
    }
}

调用

public class PurchaseHandler {
    public static void purchaseHandler(PurchaseOrderMessageBody purchaseOrder) {
        PurchaseTypeBasic operation = OperatePurchaseTypeBasic.getOperation((purchaseOrder.getOrderType())).orElseThrow(
                ()-> new IllegalArgumentException("Invalid Operator")
        );
        operation.purchaseHandler(purchaseOrder);
    }
}

public class Test {
    private static final String[] orderTypes = {"XSD_PC", "TRIANGULAR"};
    public static void main(String[] args) {
        PurchaseOrderMessageBody purchaseOrder = new PurchaseOrderMessageBody();
        for (String orderType : orderTypes) {
            purchaseOrder.setOrderType(orderType);
            PurchaseHandler.purchaseHandler(purchaseOrder);
        }
    }
}

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

3.2. 使用枚举

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

public enum PurchaseTypeEnum{
    XSD_PC{
        @Override
        public boolean handler(PurchaseOrderMessageBody purchaseOrder) {
            return CreatePurchaseHandler.handler(purchaseOrder);
        }
    },
    TRIANGULAR{
        @Override
        public boolean handler(PurchaseOrderMessageBody purchaseOrder) {
            return PurchaseFinishHandler.handler(purchaseOrder);
        }
    };

    public abstract boolean handler(PurchaseOrderMessageBody purchaseOrder);
}

不同的操作对应的逻辑不一样

public class CreatePurchaseHandler {
    public static boolean handler(PurchaseOrderMessageBody purchaseOrder) {
        System.out.println("创建采购履约单");
        return true;
    }
}

public class CreatePurchaseHandler {
    public static boolean handler(PurchaseOrderMessageBody purchaseOrder) {
        System.out.println("创建采购履约单");
        return true;
    }
}

调用时直接传入枚举值

public class OperateHandler {
    public boolean handler(PurchaseOrderMessageBody purchaseOrder, PurchaseTypeEnum purchaseTypeEnum) {
        return purchaseTypeEnum.handler(purchaseOrder);
    }
}

public class Test {
    private static final String[] orderTypes = {"XSD_PC", "TRIANGULAR"};
    public static void main(String[] args) {
        PurchaseOrderMessageBody purchaseOrder = new PurchaseOrderMessageBody();
        OperateHandler operateHandler = new OperateHandler();
        for (String orderType : orderTypes) {
            purchaseOrder.setOrderType(orderType);
            operateHandler.handler(purchaseOrder, PurchaseTypeEnum.valueOf(orderType));
        }
    }
}

3.3. 命令模式

定义命令接口

public interface Command {
    boolean execute();
}

实现不同业务

public class CreatePurchaseCommand implements Command {

    private PurchaseOrderMessageBody purchaseOrder;

    public CreatePurchaseCommand(PurchaseOrderMessageBody purchaseOrder) {
        this.purchaseOrder = purchaseOrder;
    }

    @Override
    public boolean execute() {
        System.out.println("创建采购履约单");
        return true;
    }
}

public class FinishPurchaseCommand implements Command {

    private PurchaseOrderMessageBody purchaseOrder;

    public FinishPurchaseCommand(PurchaseOrderMessageBody purchaseOrder) {
        this.purchaseOrder = purchaseOrder;
    }

    @Override
    public boolean execute() {
        System.out.println("通知采购履约完成");
        return true;
    }
}

定义一个PurchaseExecute类,加入执行命令的方法。

public class PurchaseExecute {
    public boolean execute(Command command) {
        return command.execute();
    }
}

测试代码

public class Test {
    public static void main(String[] args) {
        PurchaseOrderMessageBody purchaseOrder = new PurchaseOrderMessageBody();
        purchaseOrder.setOrderType("XSD_PC");
        PurchaseExecute purchaseExecute = new PurchaseExecute();
        purchaseExecute.execute(new CreatePurchaseCommand(purchaseOrder));
    }
}

3.4. 规则引擎

定义规则接口

public interface Rule {
    booleanevaluate(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 AddRuleimplementsRule {
    @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());
}