Java interface: calling an implementation class based on object types

I have an interface, and its 2 implementations say:

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 } } 

Now the caller who uses this interface looks like this:

 public void caller(VehicleType vehicleType, List<String> vehicleNames ) { ObjectProcessor processor = null ; if (VehicleType == VehicleType.CAR) { processor = new CarImpl(); processor.process(vehicleNames); } } 

VehicleType is ENUM that works great. But anyway, I can name the interface dynamically without using adding if statements. In the future, if I support another vehicle, I need to add an if statement along with a new interface implementation. How can i avoid this?

+8
java
source share
3 answers

Overwrite the abstract factory method in an enumeration like this.

 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 combines enumeration with factory.

Or you can use all the logic in an enumeration like this.

 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(); } 

In this case, you no longer need implementation classes (CarImpl, VanImpl, ...).

+5
source share

Use the Factory template. Here are some benefits to using: http://javarevisited.blogspot.com/2011/12/factory-design-pattern-java-example.html#ixzz3ueUdV947

1) Does the Factory method design pattern separate the calling class from the target class, which leads to less related and highly connected code?

2) Factory in Java allows subclasses to provide an extended version of an object, since creating an object inside Factory is more flexible than creating an object directly on the client. Because the client works at the interface level every time you can improve the implementation and return from Factory.

3) Another advantage of using the Factory design pattern in Java is that it encourages consistency in code, because every time an object is created using Factory, rather than using a different constructor on the other side of the client.

4) Code written using the Factory design template in Java is also easily debugged and eliminated, since you have a centralized method of creating an object, and each client receives the object from the same place

0
source share

You basically implement the Factory pattern as suggested in other answers. But in the end, you will have to write an β€œif” or β€œswitch” statement to choose to fix the implementation (or strategy) for your enum value. But, as you already mentioned, you will have to expand this selection template whenever you add or remove an enumeration value. You can get around this using a map like this:

 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); } } 

You cannot configure your ProcessorSelector by passing a map with all processor implementations mapped to the correct enumeration value (note that I used guava ImmutableMap to conveniently build a hash map:

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

You no longer have to change your ProcessorSelector, only the construction / configuration of the class. In fact, you could say that we just implemented a strategy diagram here. These selector classes are very common, and if you feel that you implement them quite often, you can even use a more general implementation, I recently described this on the blog: https://hansnuttin.wordpress.com/2015/12/03/functionselector/

0
source share

All Articles