我有Foo.java
,这是界面。
许多实现它的类。 Bar1.java , Bar2.java
等。
我在前端有一个方法,就像这样:getBar(String bar)
我可以这样做:
if(bar.equals("Bar1")) {
return new Bar1();
}
但我可以以某种方式做到这一点,每次新的实现Foo.java
,然后我不必使用新的ELSE
语句更新我的方法。
我认为每当我创建它时,每个实现都有唯一的ID或其他内容,我将其添加到BarX.java
。
有任何建议或想法吗?我想也许我可以使用enum
或smthing或任何其他解决方案。
答案 0 :(得分:2)
仅供参考:你当然意识到你不应该这样写:
if(bar == "Bar1") {
return new Bar1();
}
你应该这样做:
if("Bar1".equals(bar)) {
return new Bar1();
}
看起来你需要一个工厂(也就是虚拟构造函数)。如果您的所有Foo实现者都有默认构造函数,您可以这样做:
public class FooFactory {
public static Foo create(Class<Foo> clazz) {
return clazz.newInstance();
}
public static Foo create(String className) {
return create(Class.forName(className));
}
}
有待处理的例外情况;我没有时间为你拼出它们。你应该看到这个想法。你需要做的就是写一个新的类,你的工厂可以处理它。
如果有其他构造函数,只需使用参数和其他调用来详细说明主题。这应该可以帮到你。
答案 1 :(得分:2)
听起来像是依赖注入或反射的工作。
你可以这样做:
Class myClass = Class.forName("my.namespace.MyClass");
那将是反思。不是很好,但做的工作。
答案 2 :(得分:1)
您可以按类名创建对象:
Class<?> clazz = Class.forName(className);
Object object = ctor.newInstance();
或者如果你需要调用特定的构造函数(例如String
个参数strArgument
):
Constructor<?> c = clazz.getConstructor(String.class);
Object object = c.newInstance(new Object[] { strArgument });
答案 3 :(得分:0)
这是一个典型的工厂模式问题。
解决方案是每当你需要维护静态地图时,无论何时你有新的“条形”类型,你都需要先在地图中注册它,所以无论何时你想要一个这种类型的对象,你都可以从地图。
考虑以下类
interface IVehicle {
public void drive();
public void stop();
}
class Car implements IVehicle {
public void drive(){
//logic goes here
}
public void stop(){
//logic goes here
}
}
class VehicleFactory{
public IVehicle createVehicle(String VehicleType){
IVehicle vehicle = null;
if("Car".equalsIgnoreCase(VehicleType) ){
vehicle = new Car();
}
if("Bus".equalsIgnoreCase(VehicleType) ){
//vehicle = new Bus();
}
if("Train".equalsIgnoreCase(VehicleType) ){
//vehicle = new Train();
}
return vehicle;
}
}
所以每当你有一种新型车辆时,你必须通过添加新型车辆的代码来改变方法。
解决方法是改进VehicleFactory类,如下所示,所有车辆类型都应在地图中注册,如下所示。
class Car implements IVehicle {
static{
VehicleFactoryFlexible.registerVehicle("Car", new Car());
}
public void drive(){
//logic goes here
}
public void stop(){
//logic goes here
}
public IVehicle createVehicle(){
return (IVehicle) new Car();
}
}
public class VehicleFactoryFlexible {
static Map vehicleRegistry = new HashMap();
public static void registerVehicle(String vehicleType, IVehicle veh){
vehicleRegistry.put(vehicleType, veh);
}
public IVehicle createVehicle(String vehicleType){
IVehicle vehicle = (IVehicle)vehicleRegistry.get(vehicleType);
return vehicle.createVehicle();
}
}
答案 4 :(得分:0)
- Reflection
是要走的路......
- 但你仍然可以使用像这样的方法
public static Foo createObj(Class<Foo> clazz) {
return clazz.newInstance();
}
- 是的,它应该是equals()
而不是 ==
if(bar.equals("Bar1")) {
return new Bar1();
}
答案 5 :(得分:0)
使用反射,您可以扫描整个包中的所有BarX类,并使用此列表实例化,如果您的输入存在于列表中。或者您可以使用Class.forName解决方案直接捕获错误。 编辑:检查出http://code.google.com/p/reflections/