Java接口:根据对象类型

时间:2015-12-18 06:06:42

标签: java

我有一个界面,其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语句以及该接口的新实现。我怎么能避免这个?

3 个答案:

答案 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/