1

我有一个设计问题要问。到目前为止我还没有写任何代码,只是在思考如何实现这一点。我有一个 A 类型的对象,它包含一个 B 类型的对象。我希望 B 定义一个对象类别(接口或抽象类?)。然后我有一个 xml 文件,它定义了 B 应该是的子类型。例如,如果 B 是一个名为 Driveable 的接口,那么“car”或“truck”可能会在 xml 中定义为类型 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 的类型硬编码到我的工厂方法中。如果我上面的内容是带有工厂方法的非常标准的协议,那么我可以用这种方式处理它,只是看起来不太对。

4

3 回答 3

1

您可以做的是在 xml 中定义您希望 B impls 成为的实际类名,然后像这样使用通用类构造函数(缺少错误处理):


String bimplClassname = //read from xml
Class bimplClass = Class.forName(bimplClassname);
B newB = bimplClass.getConstructor(/*arg types*/).newInstance(/*args*/);
于 2012-10-23T21:13:21.190 回答
0

我想这取决于触发创建对象的原因。如果是一些触发创建的文本,那么您现有的代码对于小型应用程序来说是可以的。你也可以选择像Guice这样的依赖注入框架。

另外,请注意,对于比较字符串,您应该使用.equals方法,而不是代码中显示的 ==。

于 2012-10-23T21:16:36.027 回答
0

根据 carnold 的示例,您可以在工厂类中创建一个映射,该映射在 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 更容易维护,但仍然需要维护它。

于 2012-10-23T21:32:42.783 回答