我有一个设计问题要问。到目前为止,我还没有编写任何代码,只是考虑如何在此处实现。我有一个A类型的对象,它包含一个B类型的对象。我希望B定义一个对象类别(接口或抽象类?)。然后我有一个xml文件,定义了B应该是的子类型。例如,如果B是名为Driveable的接口,则可以在xml中将“car”或“truck”定义为类型A所需的Drivable对象。
我在想做的是让B成为一个接口,然后创建一个静态工厂类,它有一个工厂方法来确定应该给哪个子类型B一个xml文件。所以我的第一个问题是这是解决问题的最佳方法吗?使用抽象类而不是界面会更好吗?还是主要只是个人偏好?
其次,如果我使用接口,那么我的工厂方法就是这样做:
B createB(File f){
...
String type = ...
if(type.equals("car"))
return new CarType();
else if(type.equals("truck"))
return new TruckType();
...
return null;
}
因此,每次添加新的B子类型时,我都需要在此方法中添加另一个if语句。有没有更好的方法来做到这一点所以我要做的就是创建一个新的B子类型然后更新我的xml而不是更新工厂方法?我基本上不想将B类型的硬代码编入我的工厂方法。如果我上面提到的是非常标准的工厂方法协议,那么我就可以用这种方式来处理,只是看起来不对。
答案 0 :(得分:1)
你可以做的是在xml中定义你想要B所暗示的实际类名,然后像这样使用泛型类构造函数(缺少错误处理):
String bimplClassname = //read from xml
Class bimplClass = Class.forName(bimplClassname);
B newB = bimplClass.getConstructor(/*arg types*/).newInstance(/*args*/);
答案 1 :(得分:0)
我想这取决于触发创建对象的因素。如果是某些触发创建的文本,那么现有代码适用于小型应用程序。您还可以选择依赖注入框架,如Guice。
另外,请注意,为了比较字符串,您应该使用.equals
方法,而不是代码中显示的==。
答案 2 :(得分:0)
从carnold的例子开始,您可以在Factory类中创建一个映射,该映射在xml中的文本和相应的java类之间进行映射。
private final static Map<String, Class> typeMap;
static {
typeMap = new HashMap<String, Class>();
typeMap.put("car", CarType.class);
typeMap.put("truck", TruckType.class);
}
然后在你的方法中:
B createB(File f){
...
String type = ...
Class clazz = typemap.get(type);
if (clazz == null){
return null;
}
B newB = clazz.getConstructor(/*arg types*/).newInstance(/*args*/);
return newB;
}
比if / else稍微容易维护,但仍然需要维护它。