Java DocumentBuilderFactory#newInstance() 如何是抽象工厂模式的一个例子?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19593661/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 18:37:05  来源:igfitidea点击:

How DocumentBuilderFactory#newInstance() is an example of Abstract factory pattern?

javadesign-patternsfactory-pattern

提问by M Sach

What is Abstract Factory Pattern :-

什么是抽象工厂模式:-

It provides a way where a top level factory encapsulate a group of individual factories that are further able to create the family of related products without specifying their concrete classes.

它提供了一种方法,其中顶级工厂封装一组单独的工厂,这些工厂可以进一步创建相关产品系列,而无需指定它们的具体类。

As per Examples of GoF Design Patterns in Java's core librariesbelow is cited as example of Abstract pattern

根据以下Java 核心库的 GoF 设计模式示例被引用为抽象模式的示例

javax.xml.parsers.DocumentBuilderFactory#newInstance()

javax.xml.parsers.DocumentBuilderFactory#newInstance()

But i am not sure how come its following the Abstract Factory Pattern here.

但我不确定它是如何在这里遵循抽象工厂模式的。

Is DocumentBuilderFactoryconsidered as top level factory which internally cotains individual factory i.e DocumentBuilderFactory#newInstance()which is able to create the family of related products without specifying their concrete classes (as it just return the DocumentBuilderFactorynot any specific implementation). Is this correct?

DocumentBuilderFactory认为是内部包含单个工厂的顶级工厂,即DocumentBuilderFactory#newInstance()能够创建相关产品系列而无需指定其具体类(因为它只返回DocumentBuilderFactory非任何特定实现)。这样对吗?

采纳答案by Maxim Shoustin

Reference

参考

What is a factory pattern?

什么是工厂模式?

A Factory method pattern(aka Factory pattern) is a creational pattern. The creational patterns abstract the object instantiation process by hidinghow the objects are created and make the system independent of the object creation process.

工厂方法图案(又名工厂模式)是一个创建模式。创建模式通过隐藏对象的创建方式来抽象对象实例化过程,并使系统独立于对象创建过程。

An Abstract factory patternis one level of abstraction higher than a factory method pattern which means it returns the factory classes.

一个抽象工厂模式是抽象的层次上高于这意味着它返回工厂类工厂方法图案。

enter image description here

在此处输入图片说明

Abstract factory pattern example

抽象工厂模式示例

Const

常量

public interface Const {
    public static final int SHAPE_CIRCLE =1;
    public static final int SHAPE_SQUARE =2;
    public static final int SHAPE_HEXAGON =3;
}

ShapeFactory

形状工厂

public abstract class ShapeFactory {
    public abstract Shape getShape(int shapeId);
}

In addition to SimpleShapeFactorywe create new one:

除了SimpleShapeFactory我们创建新的:

ComplexShapeFactory

复杂形状工厂

public class ComplexShapeFactory extends ShapeFactory {
    public Shape getShape(int shapeTypeId){
        Shape shape = null;
        if(shapeTypeId == Const.SHAPE_HEXAGON) {
            shape = new Hexagon();//complex shape
        }
        else{
            // drop an error
        };
        return shape;
    }
}

Now let's create at the abstract factory, which returns one of the types of ShapeFactory:

现在让我们在抽象工厂中创建,它返回以下类型之一ShapeFactory

ShapeFactoryType

形状工厂类型

public class ShapeFactoryType {
    public static final int TYPE_SIMPLE = 1;
    public static final int TYPE_COMPLEX = 2;

    public ShapeFactory getShapeFactory(int type) {
        ShapeFactory sf = null;
        if(type == TYPE_SIMPLE) {
            sf = new SimpleShapeFactory();
        }
        else if (type == TYPE_COMPLEX) {
            sf = new ComplexShapeFactory();
        }
        else throw new BadShapeFactoryException("No factory!!");
        return sf;
    }
}

And now the main call:

现在主要调用:

      ShapeFactoryType abFac = new ShapeFactoryType();

    ShapeFactory factory = null;
    Shape s = null;
    //returns a ShapeFactory but whether it is a
    //SimpleShapeFactory or a ComplexShapeFactory is not known to the caller.
    factory = abFac.getShapeFactory(1);//returns SimpleShapeFactory
    //returns a Shape but whether it is a Circle or a Pentagon is
    //not known to the caller.
    s = factory.getShape(2); //returns square.
    s.draw(); //draws a square
    //returns a ShapeFactory but whether it is a
    //SimpleShapeFactory or a ComplexShapeFactory is not
    //known to the caller.
    factory = abFac.getShapeFactory(2);
    //returns a Shape but whether it is a Circle or a Pentagon is
    //not known to the caller.
    s = factory.getShape(3); //returns a pentagon.
    s.draw(); //draws a pentagon

From DocumentBuilderFactory

来自 DocumentBuilderFactory

The DocumentBuilderFactoryis like ShapeFactoryTypein example.

DocumentBuilderFactory是像ShapeFactoryType例如英寸

The newInstance(String factoryClassName,ClassLoader classLoader)returns new instance of a DocumentBuilderFactorybased on factoryClassName(in my case I used abFac.getShapeFactory(1);and abFac.getShapeFactory(2);).

newInstance(String factoryClassName,ClassLoader classLoader)返回的新实例DocumentBuilderFactory基础上factoryClassName(在我的情况下,我使用的abFac.getShapeFactory(1);abFac.getShapeFactory(2);)。

回答by tom

DocumentBuilderFactory#newInstance()gives you a DocumentBuilder, which is a factory for Documents.

DocumentBuilderFactory#newInstance()给你一个DocumentBuilder,它是Documents的工厂。

So DocumentBuilderFactoryis a factory that produces factories, or in other words, an abstract factory. This is required because there are many implementations of DocumentBuilderdepending on JDK version and installed libraries.

所以DocumentBuilderFactory是一个工厂,生产工厂,或者换句话说,一个抽象工厂。这是必需的,因为有许多DocumentBuilder依赖于 JDK 版本和已安装库的实现。

Does that clear it up?

这样就清楚了吗?

回答by Paul Vargas

The default implementation included in the JDK is com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl, but there are several implementations (factories). e.g.:

JDK 中包含的默认实现是com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl,但有几个实现(工厂)。例如:

  • com.google.gdata.util.common.xml.parsing.SecureGenericXMLFactory
  • com.icl.saxon.om.DocumentBuilderFactoryImpl
  • com.meterware.httpunit.dom.DocumentBuilderFactoryFilter
  • com.sun.msv.verifier.jaxp.DocumentBuilderFactoryImpl
  • net.sf.saxon.dom.DocumentBuilderFactoryImpl
  • org.allcolor.xml.parser.CDocumentBuilderFactory
  • ...
  • com.google.gdata.util.common.xml.parsing.SecureGenericXMLFactory
  • com.icl.saxon.om.DocumentBuilderFactoryImpl
  • com.meterware.httpunit.dom.DocumentBuilderFactoryFilter
  • com.sun.msv.verifier.jaxp.DocumentBuilderFactoryImpl
  • net.sf.saxon.dom.DocumentBuilderFactoryImpl
  • org.allcolor.xml.parser.CDocumentBuilderFactory
  • ...

In order to get the implementation to use (with the method newInstance()), in the javadoc of javax.xml.parsers.DocumentBuilderFactoryyou can read:

为了获得要使用的实现(使用方法newInstance()),javax.xml.parsers.DocumentBuilderFactory您可以在 javadoc 中阅读:

Obtain a new instance of a DocumentBuilderFactory. This static method creates a new factory instance. This method uses the following ordered lookup procedure to determine the DocumentBuilderFactoryimplementation class to load:

  • Use the javax.xml.parsers.DocumentBuilderFactorysystem property.
  • Use the properties file "lib/jaxp.properties"in the JRE directory. This configuration file is in standard java.util.Properties format and contains the fully qualified name of the implementation class with the key being the system property defined above. The jaxp.propertiesfile is read only once by the JAXP implementation and it's values are then cached for future use. If the file does not exist when the first attempt is made to read from it, no further attempts are made to check for its existence. It is not possible to change the value of any property in jaxp.propertiesafter it has been read for the first time.
  • Use the Services API (as detailed in the JAR specification), if available, to determine the classname. The Services API will look for a classname in the file META-INF/services/javax.xml.parsers.DocumentBuilderFactoryin jars available to the runtime.
  • Platform default DocumentBuilderFactoryinstance.

Once an application has obtained a reference to a DocumentBuilderFactoryit can use the factory to configure and obtain parser instances.

获取 a 的新实例DocumentBuilderFactory。此静态方法创建一个新的工厂实例。此方法使用以下有序查找过程来确定DocumentBuilderFactory要加载实现类

  • 使用javax.xml.parsers.DocumentBuilderFactory系统属性。
  • 使用"lib/jaxp.properties"JRE 目录中的属性文件。此配置文件采用标准 java.util.Properties 格式,并包含实现类的完全限定名称,键是上面定义的系统属性。jaxp.propertiesJAXP 实现只读取该文件一次,然后缓存它的值以备将来使用。如果第一次尝试读取文件时该文件不存在,则不会再尝试检查它是否存在。jaxp.properties第一次读取后,无法更改任何属性的值。
  • 如果可用,请使用服务 API(如 JAR 规范中所述)来确定类名。服务 API 将META-INF/services/javax.xml.parsers.DocumentBuilderFactory在运行时可用的 jar文件中查找类名。
  • 平台默认DocumentBuilderFactory实例。

一旦应用程序获得了对 a 的引用,DocumentBuilderFactory它就可以使用工厂来配置和获取解析器实例。