JDK DOM解析器:为什么需要工厂?

3

我目前正在使用JDK的标准DOM解析器进行XML解析。

然而,我认为现在是理解工厂模式的好时机。之前我尝试找到工厂模式的实用性例子,但很多解释都试图使用以下示例:

“如果用户将“Dog”输入为字符串,我们可以使用AnimalFactory识别“Dog”并实例化相应的对象,在运行时不知道我们需要什么时非常有用。”

这些例子并没有真正让我明白工厂模式的重点(也许是因为我忽略了某些东西),我觉得理解为什么在JDK的标准DOM解析器中实现工厂模式会真正帮助我(以及其他人)。所以在这里:

我读到读取XML文档需要实例化一个DocumentBuilder对象-只能从DocumentBuilderFactory对象中检索,如下所示:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();

现在我们可以像这样将一个文件对象传递给它:
File myFile = Paths.get(fooPath).toFile();
builder.parse(myFile);

但是,为什么要使用工厂模式来处理进程?为什么上面的方法比DocumentBuilder拥有自己显式构造函数并以同样的方式传递文件更好呢?
在这种情况下,只是将有相似用途的对象的构造函数进行组织吗?
提前感谢。
2个回答

3

DocumentBuilderFactory.newInstance()方法将返回以下两种实现之一:

  1. "javax.xml.parsers.DocumentBuilderFactory"。

如果不存在上述选项,则返回以下实现:

  1. "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl"。

我不能百分之百确定,但在这种特定情况下,它似乎想要为您提供一个较新的DocumentBuilderFactory实现(附带JRE)。如果没有找到,则使用旧版本。

工厂模式的威力在于,它将返回可直接使用且无需编写代码实现的内容。无论是来自java.xml.parsers包还是旧版的com.sun.org.apache.xerces.internal.jaxp包,我们都知道可以以相同的方式使用返回的内容。将来,如果创建了新的XML解析器(可能更快),并且决定替换javax.xml中的解析器,对于使用API的编码人员而言,这都无关紧要 - 它们将“正常工作”。他们将受益于新代码(如果有)或使用先前的任一实现。

工厂是一种“创建型模式”。您可以返回多种类型的可以以相同方式操作(由程序员)的对象。

当你编写代码时,如果你发现自己要做很多这样的事情:

MyObject genericObject = null;

if mySetting.equals("dog") {
    genericObject  = new Dog();
} else if { mySetting.equals("cat") {
    genericObject  = new Cat();
} 
genericObject.speak();

您可以通过让工厂创建正确的对象来节省时间。如果您引入一个Snake(),那么您只需要在一个地方更新创建代码。
该模式通常用于创建具有相同契约(接口)的对象,因此通常有助于多态性。
如果有什么不清楚的,请告诉我,我会更新我的答案。
这是我最喜欢的设计模式书中的一章: Head First Design Patterns。链接

1
在JAXP接口的情况下,使用工厂模式是为了使应用程序能够在不被“锁定”到特定JAXP接口实现的情况下编写;相反,它允许根据外部配置(例如,类路径上的内容和系统属性的值)在运行时选择实现库。这种方法有好有坏。虽然它确实使从一个实现切换到另一个实现变得非常容易(例如从Xalan切换到Saxon),但也可能使应用程序在未经测试的XML解析器或XSLT引擎上执行,如果运行时配置不正确,则应用程序可能会以不可预测的方式失败,例如,由于类路径上存在Saxon而导致原本针对Xalan编写和测试的应用程序失败并不罕见。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接