关于java中工厂方法的设计实现

时间:2012-10-23 21:06:37

标签: java interface abstract-class factory-pattern

我有一个设计问题要问。到目前为止,我还没有编写任何代码,只是考虑如何在此处实现。我有一个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类型的硬代码编入我的工厂方法。如果我上面提到的是非常标准的工厂方法协议,那么我就可以用这种方式来处理,只是看起来不对。

3 个答案:

答案 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稍微容易维护,但仍然需要维护它。