通用和工厂模式

时间:2016-11-29 21:06:53

标签: java

我们说我有一个抽象类Element和一个接口Model

Element有一个方法setModel(Model model)

Say Element实例通常引用单个Model实现实例,例如从ReST反序列化,序列化为SQL元组等。

每个Element子类都与一个特定的Model相关联,但任何Model都可能与任意数量的Element类相关联,所以像这样:

public abstract class Element<M extends Model> {
  private M mModel;
  public void setModel(M model) {
    mModel = model;
  }
}

public interface Model {
  // .. stuff
}

现在让我们说我想创建一个从模型中生成元素的工厂。鉴于Model可能连接到许多Element类,我们可以期望我们需要提供特定的类。所以最终的结果是这样的:

ElementSubclass e = new ElementFactory(ElementSubclass.class).from(someModelInstance);

...或

ElementFactory factory = new ElementFactory(ElementSubclass.class);
for(Model model : listOfModels) {
  ElementSubClass element = factory.from(model);
  listOfElementSubClassInstances.add(element);
}

到达那里并不像我想象的那么简单。我最终得到了类似的东西:

public class ElementFactory {

  private Class<? extends Element> mElementClass;

  public <E extends Element> ContentModelElementFactory(Class<E> elementClass) {
    mElementClass = elementClass;
  }

  public <E extends Element> E from(Model model) {
    try {
      Element e = mElementClass.newInstance();
      e.setModel(model);
      return (E) e;
    } catch (Exception ex) {
      //
    } 
    return null;
  }

}

似乎有点不稳定,而且lint抱怨对setModel的调用和下面一行的演员。

我考虑过像new ElementFactory<ElementSubclass>(ElementSubclass.class)这样的东西,但是读得很差 - 我们已经指定了一次子元素,看起来像是一个类型和一个参数都很苛刻。

还有静态版本,例如public static <E extends Element> E create(Class<E> clazz, Model model),但显然它不是可重复使用的真正工厂,而且看起来不那么优雅。

有没有更好的方式表达这个想法?

1 个答案:

答案 0 :(得分:1)

由于删除了泛型类型,因此您必须将ElementSubclass传递给工厂,而无法解决此问题。

如果您对new ElementFactory<ElementSubclass>(ElementSubclass.class)感到恼火,请编写一般的静态方法,例如public static <E extends Element> ElementFactory<E> of(Class<E> elementClass)。这将为您提供如下代码:

ElementFactory<ElementSubclass> factory = ElementFactory.of(ElementSubclass.class);

感觉好一些。