December
Паттерн Factory Method (Фабрика)
Posted in: Паттерны проектирования |
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.
А пока что я с удовольствием выслушаю ваши вопросы, замечания и комментарии.
13 Comments »
RSS feed for comments on this post. TrackBack URI
Приятная и полезная статья, спасибо большое.
Спасибо за краткость, теперь мне стало более понятны принципы образцов J2EE.
Спасибо, хорошее описание ![]()
Не могли бы вы еще также описать следующие паттерны :
Observer
Visitor
Iterator
Adapter
Заранее благодарна.
2MouseE: Вот это комментарий :). Обязательно напишу. Скорее всего в ближайшей статье по паттернам расскажу об Adapter’е.
Не вижу принципиальной разницы между Strategy и Factory. В одном случае создается потомок с нужным функционалом, в другом - для достижения нужного функционала создается потомок/реализация. Странно что это разные паттерны.
Работаю в области конструирования аппаратуры. Не специалист в области программирования.Подскажите как в рамках CALS-технологий создать описание электрорадиоэлементов и связей между ними на основе паттернов.
Элемент имеет: производителя и поставщика;совокупность технических характеристик; чертеж; ;связность в схеме принципиальной и т.д. Участвует в различных отношениях, во многих предметных областях (торговая сеть, преобразование сигнала, монтаж аппаратуры и т.д.)
Наверное не совсем удачный пример этого паттерна. Он, действительно больше напоминает Стратегию, а Factory Method - это производящий шаблон и должен выдать некий продукт.
Странно. Зачем AbstractWriter делать абстрактным классом, когда можно вместо него сделать интерфейс :/ Вообще не понятный ход.
Sergey Zwezdin
Ты прав, но это детали. Просто представь что есть этот интерфейс, а абстракный клас его имплементирует и добавляет НЕКИЙ(но не весь) функционал. В данном случае видем просто сокращенный вид кода.
а почему метод getWriter не static?
не вижу смысла в данном случае создавать экземпляр класса FactoryMethod…
спасибо!
to Sergey Zwezdin and Andrey Yasinetskiy: да, конечно, можно AbstractWriter сделать интерфейсом, можно метод getWriter сделать статическим. Но зачем завязываться на то, что AbstractWriter и FactoryMethod никогда не будут иметь внутреннего состояния или же что AbstractWriter не будет иметь поведения характерного для всех Writer’ов?
автору за старание большое пасибо, но все же статьи не очень хорошие, лично мне вообще ничего не понятно.
Насколько я понял в примере (за примеры в цикле о паттернах отдельное спасибо) проиллюстрирована параметрирозованная фабрика, т. к. в фабричный метод передаётся параметр, на основе которого и создаётся конкретный подкласс AbstractWriter. Между тем, классическая фабрика, насколько я понял, ведёт себя несколько иначе: “класс спроектирован так, чтобы объекты, которые он создает, специфицировались подклассами” (Э. Гамма ‘Паттерны проектирования’). То есть должно быть несколько наследников FactoryMethod для каждого наследника AbstractWriter, а выбор остаётся за клиентом, какую из реализацию FactoryMethod выбрать. Я правильно понял?