首页 > 解决方案 > 避免类似检查的 if 条件

问题描述

无论如何,是否有条件避免这些情况?因为可能有不同类型的物体进来。

if ("OpenOrder".equals(order.getClass().getSimpleName())) {
    return OpenOrderBuilder.createOFSMessage((OpenOrder) order); //Returns String
}
if ("ExecutionOrder".equals(order.getClass().getSimpleName())) {
    return ExecutionOrderBuilder.createOFSMessage((ExecutionOrder) order); //Returns String
}

标签: javajava-8

解决方案


有很多方法可以做到这一点。选择哪一个取决于您的需求,在这种情况下尤其取决于您将拥有多少不同类型的对象。我建议查看接口和继承等概念以及特定的设计模式。

One approach I tend to like, although still not perfect, works as follows:

interface Order {

}

interface OrderBuilder<T> {
    T forType();
    Object createOFSMessage(Order order);
}

class OpenOrderBuilder<OpenOrder> implements OrderBuilder {
    @Override
    OpenOrder forType() {
        return OpenOrder.class;
    }
    ...
}

class ExecutionOrderBuilder<ExecutionOrder> implements OrderBuilder {
    @Override
    ExecutionOrder forType() {
        return ExecutionOrder.class;
    }
    ...
}

class MyProcessor {
    Map<Class, OrderBuilder> obs;

    public void initialize() {
        List<OrderBuilder> builders = new ArrayList<>();
        builders.add(new OpenOrderBuilder());
        builders.add(new ExecutionOrderBuilder());

        obs = new HashMap<Class, OrderBuilder>();
        for(OrderBuilder b : builders) {
            obs.put(b.forType(), b);
        }
    }

    public Object createOFSMessage(Order order) {
        return obs.get(order.getClass()).createOFSMessage(order);
    }
}

In the above example, adding a new implementation would just consist of adding an entry to the builders collection. While in the example above it's done manually, normally this is done through Dependency Injection and frameworks like spring (in which case, the initialize method may turn into a constructor with builders as an @Autowired argument).

There are of course other ways, some more simple some more complicated. The best way really depends on what you have to do and one key rule: the less code you have the better.


推荐阅读