Skip to content

Latest commit

 

History

History

factoryMethod

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 

Порождающие шаблоны / Фабричный метод

Фабричный метод (Factory Method)

Другие названия

  • Виртуальный конструктор (Virtual Constructor)

Содержание

Описание паттерна

Абстрактная ситуация. Машины и моторы

Вы производите на заводе три вида машин: Маленькую, Среднюю и Большую. Они очень похожи, но для работы им нужны разные моторы. В каком месте класса Машины нужно указать, какой мотор ей нужен?

Лучше, если создание мотора нужного типа будет вынесено в отдельный метод. Тогда вы легко сможете переопределить его у любого класса машины.


Фабричный метод выносится на самый верх иерархии классов (в родительский или абстрактный класс). То есть у класса есть некоторый метод, который производит объект, который нужен классу - Фабричный метод. Этот метод может быть абстрактным, чтобы каждый дочерний класс дал собственную реализацию или иметь некоторое дефолтное поведение (например, возвращать самый простой мотор).

Конкретная реализация фабричного метода предоставляется дочерними классами. Таким образом, каждый дочерний класс сам решает, какой именно объект создавать. МаленькаяМашина создает себе МаленькийМотор, а БольшаяМашина - БольшойМотор. При этом вся логика по выбору и созданию мотора находится в одном месте - в фабричном методе.

Реализация паттерна

Схема паттерна Фабричный метод

  • Иерархия создателей:
    • Родительский класс Creator определяет фабричный метод для создания объекта FactoryMethod().
    • Конкретные создатели ConcreteCreator реализуют этот метод по-своему.
  • Иерархия продуктов:
    • Порождаемые классы (продукты) тоже объединяются в отдельную иерархию, ведь они являются родственными и должны иметь одинаковый интерфейс. Класс Product предоставляет общий интерфейс продукта.
    • Классы ConcreteProduct определяют конкретные продукты.
  • Каждый КонкретныйСоздатель в своей реализации ФабричногоМетода создает тот КонкретныйПродукт, который ему нужен.

Как именно создается Продукт не имеет значения. Это может быть обычное создание нового объекта через конструктор, или получение объекта из некоторого хранилища, или переиспользование другого объекта.

Важно:

  • Продукты имеют одинаковый интерфейс.
  • Фабричный метод возвращает Продукт или объект с интерфейсом Продукта.
  • Фабричный метод - лишь один из методов Создателя, которых может быть много.

Не важно:

  • Логика создания/получения Продукта внутри фабричного метода.

Расширение

Чтобы добавить поддержку нового Продукта, нужно создать новый подкласс Создателя и реализовать у него соответствующий фабричный метод.

Примеры

Использование

  • Неизвестно заранее, с каким типом объектов придется работать коду. Вынесение создания Продукта в отдельный метод позволяет легче им управлять.
  • Нужна возможность расширения иерархии создателей. Например, вы создаете еще один тип машины - Трактор. Чтобы дать ему правильный мотор, нужно только реализовать фабричный метод класса.

Преимущества

  • Абстрагирует создание продукта, убирает лишние привязанности.
  • Упрощает поддержку кода создания продукта.
  • Упрощает добавление новых продуктов и создателей.
  • Позволяет расширять и усложнять логику создания/переиспользования продуктов.

Недостатки

  • Иерархии создателей и продуктов быстро разрастаются.
  • Для каждого нового типа Продукта нужен свой Создатель.

Похожие паттерны

При усложнении паттерн Фабричный метод обычно следует заменить одним из этих паттернов. Например, если в системе много продуктов, которые создаются Фабричным методом, имеет смысл создать отдельную Фабрику для их прозводства. Такая Фабрика может иметь несколько методов, каждый из которых является фабричным и производит определенный продукт. Если у вас есть несколько наборов продуктов (например, в разных стилях), можно создать несколько таких Фабрик. Для управления ими используйте паттерн Абстрактная фабрика.

Взаимодействие с другими паттернами

Использование паттерна в структуре другого паттерна (один паттерн является частью другого)

Способы реализации паттерна (вариации механизмов работы паттерна)

Частое применение (паттерны не связаны напрямую)

  • Итератор (Iterator). Итераторы выступают в качестве продуктов, разным подклассам требуются разные итераторы.

Источники