2015-12-18 86 views
8

我有一个接口,它的2个实现说:Java接口:调用一个实现类基于对象类型

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语句以及接口的新实现。我怎样才能避免这种情况?

+2

使用[* factory *](https:// en .wikipedia.org/wiki/Factory_%28object-oriented_programming%29)或[* builder *](https://en.wikipedia.org/wiki/Builder_pattern)。 –

+0

我不确定,但使用反射可以帮助你,它会消除每次添加开关盒的开销。但从时间复杂度来看,使用反射是昂贵的过程。 – Vishrant

回答

5

像这样在enum中覆盖抽象工厂方法。

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结合了枚举和工厂。

或者你可以像这样使用enum中的所有逻辑。

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,...)。

+0

谢谢!这种类型的方法正是我所需要的 – Dalu

0

使用工厂模式。这里有一些使用它的好处:http://javarevisited.blogspot.com/2011/12/factory-design-pattern-java-example.html#ixzz3ueUdV947

1)工厂方法设计模式将调用类从目标类中分离出来,从而导致耦合度较低且高度内聚的代码?

2)Java中的工厂模式使子类能够提供对象的扩展版本,因为在工厂内部创建对象比直接在客户端创建对象更灵活。由于客户端在任何时候都可以在界面级别上工作,所以您可以增强实现并从工厂返回。

3)在Java中使用工厂设计模式的另一个好处是它鼓励代码中的一致性,因为每次使用Factory创建对象时,而不是在不同的客户端使用不同的构造器。

4)在Java中使用工厂设计模式编写的代码也便于调试和故障排除,因为你必须为对象创建一个集中的方法和每一个客户是从同一个地方

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(注意我用番石榴的ImmutableMap方便地构建HashMap中:

new ProcessorSelector(ImmutableMap.of(
    VehicleType.CAR, new CarImpl(), 
    VehicleType.VAN, new VanImpl()); 

你永远不会有再次修改你的ProcessorSelector,只有类的构造/配置事实上,你可以说我们只是在这里实施的策略模式。这些选择器类是非常普遍的,如果你觉得你经常使用它们,你甚至可以使用更通用的实现,我最近在一篇博文中描述了这个:https://hansnuttin.wordpress.com/2015/12/03/functionselector/

+0

但是在您的解决方案中,每次查找都会得到相同的CarImpl或VanImpl实例。 – wastl

+0

是真的,如果你想要新的实例只需要用工厂替换实例,那么同样的原则适用 –

相关问题