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.
А пока что я с удовольствием выслушаю ваши вопросы, замечания и комментарии.
11 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’ов?