Как DocumentBuilderFactory#newInstance() является примером шаблона абстрактной фабрики?

Что такое шаблон абстрактной фабрики: -

Он обеспечивает способ, при котором фабрика верхнего уровня инкапсулирует группу отдельных фабрик, которые в дальнейшем могут создавать семейство связанных продуктов без указания их конкретных классов.

Согласно примеры шаблонов проектирования GoF в основных библиотеках Java ниже приведены в качестве примера абстрактного шаблон

javax.xml.parsers.DocumentBuilderFactory#newInstance()

Но я не уверен, почему здесь следует шаблон абстрактной фабрики.

Является ли DocumentBuilderFactory фабрикой верхнего уровня, которая внутри содержит отдельную фабрику, то есть DocumentBuilderFactory#newInstance(), которая может создавать семейство связанных продуктов без указания их конкретных классов (поскольку она просто возвращает DocumentBuilderFactory, а не какую-либо конкретную реализацию). Это правильно?


person M Sach    schedule 25.10.2013    source источник


Ответы (3)


Справочник

Что такое фабричный шаблон?

Шаблон метода Factory (шаблон Factory) – это порождающий шаблон. Шаблоны создания абстрагируют процесс создания объектов, скрывая то, как объекты создаются, и делают систему независимой от процесса создания объектов.

Абстрактный шаблон фабрики — это один уровень абстракции выше, чем шаблон метода фабрики, что означает, что он возвращает классы фабрики.

введите здесь описание изображения

Пример шаблона абстрактной фабрики

Константа

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:

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 на основе factoryClassName (в моем случае я использовал abFac.getShapeFactory(1); и abFac.getShapeFactory(2);).

person Maxim Shoustin    schedule 25.10.2013
comment
Мой вопрос заключается в том, как DocumentBuilderFactory#newInstance() следует шаблону абстрактной фабрики? - person M Sach; 25.10.2013
comment
Извините, я просто не понимаю, является ли суперкласс ShapeFactory абстрактным? - person shanehoban; 18.04.2014
comment
@shanehoban да, я добавил этот класс, чтобы ответить, спасибо - person Maxim Shoustin; 18.04.2014

DocumentBuilderFactory#newInstance() дает вам DocumentBuilder, который является фабрикой для Document.

Итак, DocumentBuilderFactory — это фабрика, которая производит фабрики, или, другими словами, абстрактная фабрика. Это необходимо, поскольку существует множество реализаций DocumentBuilder в зависимости от версии JDK и установленных библиотек.

Это проясняет ситуацию?

person tom    schedule 25.10.2013
comment
DocumentBuilderFactory#newInstance() дает вам DocumentBuilderFactory, а не DocumentBuilder - person M Sach; 25.10.2013

Реализация по умолчанию, включенная в 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()), в javadoc javax.xml.parsers.DocumentBuilderFactory вы можете прочитать:

Получите новый экземпляр DocumentBuilderFactory. Этот статический метод создает новый экземпляр фабрики. Этот метод использует следующую упорядоченную процедуру поиска для определения DocumentBuilderFactory класса реализации для загрузки:

  • Используйте системное свойство javax.xml.parsers.DocumentBuilderFactory.
  • Используйте файл свойств "lib/jaxp.properties" в каталоге JRE. Этот файл конфигурации имеет стандартный формат java.util.Properties и содержит полное имя класса реализации с ключом, являющимся системным свойством, определенным выше. Файл jaxp.properties читается реализацией JAXP только один раз, а затем его значения кэшируются для будущего использования. Если файл не существует при первой попытке чтения из него, дальнейшие попытки проверить его существование не предпринимаются. Невозможно изменить значение любого свойства в jaxp.properties после того, как оно было прочитано в первый раз.
  • Используйте API служб (как подробно описано в спецификации JAR), если он доступен, для определения имени класса. API служб будет искать имя класса в файле META-INF/services/javax.xml.parsers.DocumentBuilderFactory в jar-файлах, доступных среде выполнения.
  • Экземпляр DocumentBuilderFactory платформы по умолчанию.

Как только приложение получило ссылку на DocumentBuilderFactory, оно может использовать фабрику для настройки и получения экземпляров парсера.

person Paul Vargas    schedule 25.10.2013
comment
но как DocumentBuilderFactory#newInstance() следует шаблону абстрактной фабрики? - person M Sach; 25.10.2013
comment
Метод возвращает конкретную фабрику в зависимости от конфигурации виртуальной машины. И у каждой фабрики есть свои конкретные классы. - person Paul Vargas; 25.10.2013
comment
В таком случае Мое понимание кажется правильным. Не так ли? Вот мое понимание: - DocumentBuilderFactory считается фабрикой верхнего уровня, которая внутри содержит отдельную фабрику, т.е. DocumentBuilderFactory#newInstance(), которая может создавать семейство связанных продуктов без указания их конкретных классов (поскольку она просто возвращает DocumentBuilderFactory, а не какую-либо конкретную реализацию) . Это правильно? - person M Sach; 25.10.2013
comment
Ты прав! Этот класс использует шаблон проектирования. Чтобы использовать реализацию, просто настройте ее и вперед! - person Paul Vargas; 25.10.2013