我有以下抽象类
public abstract class Document {
private File file;
public Document(File f) {
this.file = f;
}
...
public abstract String parse();
}
目前,我有两个扩展Document
,JsonDocument
和XmlDocument
的类。
在另一个类DocumentContent中,我有一些函数可以迭代json和xml文件的一些集合,并调用parse()函数来提取某些内容。
如何根据检测到的文件扩展名动态实例化Document对象而不使用条件语句?将来会添加其他文件扩展名,我希望每次创建新的Document类类型时都不需要更新DocumentContent。
答案 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();
根据文件扩展名,您可以实例化任一类。您无需进行太多更改即可轻松添加/删除新文档。