I’ve several objects extending a bean:
public class Fruit {}
public class Banana extends Fruit {}
public class Pear extends Fruit {}
And I’ve an Interface with different implementation, one for each bean.
public interface Milkshake {
public String doMilkshake();
}
public class FruitMilkshake implements Milkshake {
public String doMilkshake() {
return "Fruit Milkshake!";
}
}
public class BananaMilkshake implements Milkshake {
public String doMilkshake() {
return "Banana Milkshake!";
}
}
public class PearMilkshake implements Milkshake {
public String doMilkshake() {
return "Pear Milkshake!";
}
}
How can I instantiate the correct implementation based on the concrete type of my bean?
For now I’ve used typization, and a Map to “map” the correct implementation.
Like this:
public void hungry(Fruit fruit) {
Map<String, String> obj2impl = new HashMap<String, String>();
obj2impl.put("Fruit", "FruitMilkshake");
obj2impl.put("Banana", "BananaMilkshake");
obj2impl.put("Pear", "PearMilkshake");
String name = fruit.getClass().getCanonicalName();
String implName = obj2impl.get(name);
Milkshake milkshake = (Milkshake) Class.forName(implName).newInstance();
milkshake.doMilkshake(fruit);
}
public interface Milkshake <T t> {
public String doMilkshake(T t);
}
public class FruitMilkshake implements Milkshake<Fruit> {
public String doMilkshake(Fruit fruit) {
return "Fruit Milkshake!";
}
}
public class BananaMilkshake implements Milkshake<Banana> {
public String doMilkshake(Banana banana) {
return "Banana Milkshake!";
}
}
public class PearMilkshake implements Milkshake<Pear> {
public String doMilkshake(Pear pear) {
return "Pear Milkshake!";
}
}
Better ways to achieve this?
Well a starting point would be to avoid reflecting on the name of the class:
Now that still requires you to have a parameterless constructor in each implementation, and it still always creates a new instance. If you use a
Provider-like concept, you can get round this:EDIT: Having reread the post, you can get rid of the text part as well, and have a
Map<Class<?>, Provider<Milkshake>>. Avoid hard-coding the names of classes if possible.Of course, if your
Fruitclass had amakeMilkshakeabstract method, that would be even nicer…