我有几个扩展bean的对象:
public class Fruit {}
public class Banana extends Fruit {}
public class Pear extends Fruit {}
我有一个不同实现的接口,每个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!";
}
}
如何根据我的bean的具体类型实例化正确的实现?
现在我使用了典型化,并使用Map来“映射”正确的实现。 像这样:
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!";
}
}
实现这一目标的更好方法是什么?
答案 0 :(得分:1)
实现这一目标的更好方法是什么?
一个出发点是避免反思课程的名称:
Map<String, Class<? extends Milkshake>> obj2impl =
new HashMap<String, Class<? extends Milkshake>>();
obj2impl.put("Fruit", FruitMilkshake.class);
obj2impl.put("Banana", BananaMilkshake.class);
...
Milkshake milkshake = obj2impl.get(text).newInstance();
现在仍需要在每个实现中都有一个无参数构造函数,而始终仍会创建一个新实例。如果你使用类似Provider
的概念,你可以解决这个问题:
Map<String, Provider<Milkshake>> map = ...;
// Fill the map with providers, some of which could create a new instance,
// and some could reuse an existing one
...
Milkshake milkshake = map.get(text).get();
编辑:重新阅读帖子后,您也可以删除文本部分,并拥有Map<Class<?>, Provider<Milkshake>>
。如果可能,请避免对类的名称进行硬编码。
当然,如果你的Fruit
班级有一个makeMilkshake
抽象方法,那就更好了......
答案 1 :(得分:0)
public class Fruit {
public Class<? extends Milkshake> getMilkshakeClass() {
return Milkshake.class;
}
}
public class Banana extends Fruit {
public Class<? extends Milkshake> getMilkshakeClass() {
return Banana.class;
}
}
public class Pear extends Fruit {
public Class<? extends Milkshake> getMilkshakeClass() {
return PearMilkshake.class;
}
}
你甚至可能想要创建一个AbstractFruit类,它将上面使用的方法作为一个必须覆盖的抽象方法
public abstract class AbstractFruit {
public abstract Class<? extends Milkshake> getMilkshakeClass();
}
而不是让他们扩展Fruit,扩展它。