Java - 动态实例化抽象子类

时间:2014-02-06 05:18:46

标签: java

我有以下抽象类

public abstract class Document {
  private File file;
  public Document(File f) {
    this.file = f;
  }

  ...

  public abstract String parse();
}

目前,我有两个扩展DocumentJsonDocumentXmlDocument的类。

在另一个类DocumentContent中,我有一些函数可以迭代json和xml文件的一些集合,并调用parse()函数来提取某些内容。

如何根据检测到的文件扩展名动态实例化Document对象而不使用条件语句?将来会添加其他文件扩展名,我希望每次创建新的Document类类型时都不需要更新DocumentContent。

3 个答案:

答案 0 :(得分:2)

您可以选择是否使用反射,无需反射就需要设计构建器,例如:

abstract class DocumentBuilder {
  public abstract Document build(File file);
}

HashMap<String, Builder> builders = new HashMap<String, Builder>();
builders.put("xml", new Builder(){ 
  public build(File file) { return new XMLDocument(file); } 
});

Builder correctBuilder = builders.get("xml");
if (correctBuilder != null)
  return correctBuilder.build()

使用反射它会类似,但你将使用反射本身给出的newInstance工具:

HashMap<String, Class<? extends Document>> builders = new HashMap<String, Class<? extends Document>>();
builders.put("xml", XMLDocument.class);

try {
  Document document = builders.get("xml").newInstance();
}
catch (...)

答案 1 :(得分:1)

一件非常简单的事情就是像DocumentFactory这样:

public class DocumentFactory {
  public static Document createFrom(File f) {
    //Produce the right kind of Document based on the File instance
  }
}

使用此功能创建所有Document

然后,由于每个文档都知道如何解析自己,所以只要始终使用Document抽象引用每个文档,就可以使用多态性:

for (Document document : documents) {
  document.parse();
}

答案 2 :(得分:0)

几年前我有一些类似的要求,并通过使用策略模式和简单工厂模式(非工厂方法模式)的组合来解决它

public class DocumentContent{
   Document document;
    //other code
}

所以现在你的DocumentContent由Document组成。这使您可以灵活地动态调用Document类的方法。我建议你最好把Document作为接口,在子类中实现。您可以实例化如下:

 document = new JsonDocument();
 //OR  
 document = new XmlDocument();

根据文件扩展名,您可以实例化任一类。您无需进行太多更改即可轻松添加/删除新文档。