3

什么是抽象工厂模式:-

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

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

javax.xml.parsers.DocumentBuilderFactory#newInstance()

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

DocumentBuilderFactory认为是内部包含单个工厂的顶级工厂,即DocumentBuilderFactory#newInstance()能够在不指定具体类的情况下创建相关产品系列(因为它只返回DocumentBuilderFactory没有任何特定实现)。这个对吗?

4

3 回答 3

4

参考

什么是工厂模式?

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

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

在此处输入图像描述

抽象工厂模式示例

常量

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

形状工厂

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

除了SimpleShapeFactory我们创建一个新的:

复杂形状工厂

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

形状工厂类型

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在示例中一样。

返回 a基于的newInstance(String factoryClassName,ClassLoader classLoader)新实例(在我的例子中,我使用了and )。DocumentBuilderFactoryfactoryClassNameabFac.getShapeFactory(1);abFac.getShapeFactory(2);

于 2013-10-25T15:22:56.913 回答
1

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

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

这样就清楚了吗?

于 2013-10-25T15:21:08.717 回答
1

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

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

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

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

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

于 2013-10-25T15:28:16.150 回答