我有一个界面,其2个实现说:
public interface ObjectProcessor {
public void process(List<String> objectNames);
}
public CarImpl implements ObjectProcessor {
@override
public void process(List<String> carNames){
//car logic
} }
public VanImpl implements ObjectProcessor {
@override
public void process(List<String> vanNames){
//van logic
}
}
现在使用此界面的调用者看起来像:
public void caller(VehicleType vehicleType, List<String> vehicleNames ) {
ObjectProcessor processor = null ;
if (VehicleType == VehicleType.CAR) {
processor = new CarImpl();
processor.process(vehicleNames);
}
}
VehicleType是ENUM 这很好用。但无论如何我可以动态调用一个接口而不用 添加if语句。将来,如果我支持其他车辆,我需要添加一个if语句以及该接口的新实现。我怎么能避免这个?
答案 0 :(得分:6)
在枚举中覆盖抽象工厂方法。
public enum VehicleType {
Car {
@Override
public ObjectProcessor createImpl() {
return new CarImpl();
}
},
Van {
@Override
public ObjectProcessor createImpl() {
return new VanImpl();
}
};
public abstract ObjectProcessor createImpl();
}
public void caller(VehicleType vehicleType, List<String> vehicleNames ) {
ObjectProcessor processor = vehicleType.createImpl();
processor.process(vehicleNames);
}
VechicleType将枚举与工厂结合起来。
或者你可以像这样记录枚举中的所有逻辑。
public enum VehicleType {
Car {
@Override
public ObjectProcessor createImpl() {
return new ObjectProcessor() {
@Override
public void process(List<String> objectNames) {
// car logic
}
};
}
},
Van {
@Override
public ObjectProcessor createImpl() {
return new ObjectProcessor() {
@Override
public void process(List<String> objectNames) {
// van logic
}
};
}
};
public abstract ObjectProcessor createImpl();
}
在这种情况下,您不再需要实现类(CarImpl,VanImpl,...)。
答案 1 :(得分:0)
使用工厂模式。以下是使用它的一些好处:http://javarevisited.blogspot.com/2011/12/factory-design-pattern-java-example.html#ixzz3ueUdV947
1)工厂方法设计模式将调用类与目标类分离,从而导致代码耦合度低且内聚性高?
2)Java中的工厂模式使子类能够提供对象的扩展版本,因为在工厂内创建对象比在客户端中直接创建对象更灵活。由于客户端在任何时候都可以在接口级别工作,因此可以增强实现并从Factory返回。
3)在Java中使用Factory设计模式的另一个好处是它鼓励Code中的一致性,因为每次使用Factory创建对象而不是在不同的客户端使用不同的构造函数。
4)使用Java中的工厂设计模式编写的代码也很容易调试和排除故障,因为您有一个集中的对象创建方法,每个客户端都从同一个地方获取对象
答案 2 :(得分:0)
你基本上实现的是像其他答案中提出的工厂模式。但最终你必须编写一个'if'或'switch'语句来选择纠正你的枚举值的实现(或策略)。但是就像你自己提到的那样,每当你添加或删除枚举值时你都必须扩展这个选择模式。您可以使用如下地图来避免这种情况:
public class ProcessorSelector {
private final Map<VehicleType, ObjectProcessor> processors;
public ProcessorSelector(Map<VehicleType, ObjectProcessor> processors) {
this.processors = processors;
}
public void process(VehicleType type, List<String> input) {
processors.get(type).process(input);
}
}
您可以通过传递一个映射来配置您的ProcessorSelector,其中所有处理器实现都映射到正确的枚举值(注意我使用了guava的ImmutableMap来方便地构造散列映射:
new ProcessorSelector(ImmutableMap.of(
VehicleType.CAR, new CarImpl(),
VehicleType.VAN, new VanImpl());
您永远不必再次更改您的ProcessorSelector,只需更改类的构造/配置。事实上你可以说我们刚刚在这里实施了战略模式。这些选择器类很常见,如果你觉得你经常使用它们,你甚至可以使用更通用的实现,我最近在博文中描述了这个:https://hansnuttin.wordpress.com/2015/12/03/functionselector/