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

时间:2013-10-25 15:17:05

标签: java design-patterns factory-pattern

什么是抽象工厂模式: -

它提供了一种方式,顶层工厂封装了一组能够进一步创建相关产品系列的单个工厂 没有指定他们的具体类。

根据下面的Examples of GoF Design Patterns in Java's core libraries引用抽象模式的例子

  

javax.xml.parsers.DocumentBuilderFactory#newInstance()

但我不确定它是如何跟随抽象工厂模式的。

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

3 个答案:

答案 0 :(得分:4)

参考

什么是工厂模式?

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

抽象工厂模式是一个高于工厂方法模式的抽象级别,这意味着它返回工厂类。

enter image description here

抽象工厂模式示例

<强> 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);
}

除了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;
    }
}

现在让我们在抽象工厂创建,它返回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;
    }
}

现在主要的电话:

      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

来自DocumentBuilderFactory

DocumentBuilderFactory就像示例中的ShapeFactoryType

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

答案 1 :(得分:1)

DocumentBuilderFactory#newInstance()为您提供DocumentBuilder,这是Document的工厂。

所以DocumentBuilderFactory是一家生产工厂的工厂,换句话说就是一家抽象工厂。这是必需的,因为DocumentBuilder有许多实现,具体取决于JDK版本和已安装的库。

这清楚了吗?

答案 2 :(得分:1)

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

  • 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
  • ...

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

  

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

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

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