Javenue logo

Javenue

Программирование на Java

Информационные технологии

Паттерн Factory Method - Фабрика

Factory Method - это паттерн создания объектов (creational pattern). Данный шаблон проектирования предоставляет интерфейс для создания экземпляров некоторого класса. В момент создания наследники могут определить, какой класс инстанциировать.

Иными словами, Фабрика делегирует создание объектов наследникам родительского класса. Это позволяет использовать в коде программы не специфические классы, а манипулировать абстрактными объектами на более высоком уровне.

Паттерн проектирования Factory встречается очень часто. Рассмотрим небольшой пример на Java.

Вступление: Требования к разного рода програмным продуктам постоянно растут. Отчеты по выполнению операций приложения должны формироваться в разном виде: XML, HTML, текст и т.д. Это как раз тот случай, когда удобно использовать паттерн Factory.

Решение: Класс AbstractWriter будет представлять абстракцию для записи в некоторый контекст (будь то XML-документ или текстовый файл).

public abstract class AbstractWriter {
    public abstract void write(Object context);
}

У этого класса может быть любое кол-во наследников. Рассмотрим подклассы ConcreteFileWriter и ConcreteXmlWriter для записи в текстовый файл и DOM документ соответственно:

public class ConcreteFileWriter extends AbstractWriter {
    public void write (Object context) {
        // method body
    }
}

public class ConcreteXmlWriter extends AbstractWriter {
    public void write (Object context) {
        // method body
    }
}

Для создания нужного нам объекта можно написать следующую Фабрику:

import java.io.File;
import org.w3c.dom.Document;

public class FactoryMethod {
    public AbstractWriter getWriter(Object object) {
        AbstractWriter writer = null;
        if (object instanceof File) {
            writer = new ConcreteFileWriter();
        } else if (object instanceof Document) {
            writer = new ConcreteXmlWriter();
        }
        return writer;
    }
}

В тексте программы при создании отчета нужно передать в функцию getWriter объект File или DOM документ. В результате выполнения метода мы получим нужный объект необходимого уровня абстракции.

Используйте паттерн Factory в следующих случаях:

  • класс не имеет информации о том, какой тип объекта он должен создать;
  • класс передает ответственность по созданию объектов наследникам;
  • необходимо создать объект в зависимости от входящих данных.

В одной из последующих статей по проектированию мы рассмотрим паттерн Abstract Factory.

А пока что я с удовольствием выслушаю ваши вопросы, замечания и комментарии.



Комментариев: 5

  Выйти

  * для публикации комментариев нужно  

danik:

Насколько я понял в примере (за примеры в цикле о паттернах отдельное спасибо) проиллюстрирована параметрирозованная фабрика, т. к. в фабричный метод передаётся параметр, на основе которого и создаётся конкретный подкласс AbstractWriter. Между тем, классическая фабрика, насколько я понял, ведёт себя несколько иначе: “класс спроектирован так, чтобы объекты, которые он создает, специфицировались подклассами” (Э. Гамма ‘Паттерны проектирования’). То есть должно быть несколько наследников FactoryMethod для каждого наследника AbstractWriter, а выбор остаётся за клиентом, какую из реализацию FactoryMethod выбрать. Я правильно понял?

alex:

На самом деле в примере показан вовсе не Factory Method, а так называемая Simple Factory (это даже не шаблон проектирования, а просто широко используемая техника). Правильно написал danik, что у класса FactoryMethod должны быть наследники, которые собственно и переопределяют фабричный метод. На первый взгляд может показаться, что нет никакого отличия, но отличие огромное. Прочитайте “Head First Design Patterns” или “Design Patterns For Dummies” и вам станет все понятно.

Igor:

to alex

Ты неправ. Это все таки фабричный метод. Читаем у Эриха Гаммы: “параметризованные фабричные методы. Это еще один вариант паттерна, который позволяет фабричному методу создавать разные виды продуктов. Фабричному методу передается параметр, который идентифицирует вид создаваемого объекта.

Все объекты, получающиеся с помощью фабричного метода, разделяют общий интерфейс Product. В примере с документами класс Application может поддерживать разные виды документов. Вы передаете методу CreateDocument лишний параметр, который и определяет, документ какого вида нужно создать”

Так что перед тем как высказывать свое мнение неплохо бы изучить мат часть

antonin yorov:

Чего то не понял, а чем это отличается он паттерна стратегия?

UA C:

Можно я тоже по умничаю. antonin yorov разница между фабрикой и стратегией в том что стратегия позволяет динамически определять нужный алгоритм (то есть можно в рантайме подключать нужный субкласс интерфейса) а фабрика при всем этом в алгоритме имеет метод который возвращает объект.