Абстрактная фабрика (паттерн - шаблон) - описание

пройдёмся по всем пунктам

Название и классификация паттерна

паттерн, порождающий объекты.

Назначение

Предоставляет интерфейс для создания семейств взаимосвязанных или взаимозависимых объектов, не специфицируя их конкретных классов.

Известен также под именем

Kit (инструментарий).

Мотивация

Нам нужно создавать семейство объектов, которые вместе образуют виджет - причём объекты разных типов но одного стиля надо группировать (чёрной машине чёрный бампер, а белой - белый) - далее пример для виджетов:
Абстрактная фабрика мотивация

Применимость

Используйте это паттерн когда:

  1. система не должна зависеть от того, как создаются, компонуются и представляются входящие в нее объекты;
  2. входящие в семейство взаимосвязанные объекты должны использоваться вместе и вам необходимо обеспечить выполнение этого ограничения;
  3. система должна конфигурироваться одним из семейств составляющих ее объектов;
  4. вы хотите предоставить библиотеку объектов, раскрывая только их интерфейсы, но не реализацию.

Структура

Обобщаем сущности задачи из мотивации - теперь мы просто группируем абстрактные объекты (в том смысле что на диаграмме бизнес логика не указывается) и предоставляем общий интерфейс для создания этих групп:
абстрактная фабрика структура - фкн вгу

Участники

В скобках для каждого участника показаны его "реальные" примеры - из "мотивации".
Итак:

  1. AbstractFactory (WidgetFactory) - абстрактная фабрика: объявляет интерфейс для операций, создающих абстрактные объекты-продукты;
  2. ConcreteFactory (MotifWidgetFactory, PMWidgetFactory) - конкретная фабрика: реализует операции, создающие конкретные объекты-продукты;
  3. AbstractProduct (Window, ScrollBar) - абстрактный продукт: объявляет интерфейс для типа объекта-продукта;
  4. ConcreteProduct (Motif Window, MotifScrol lBar) - конкретный продукт: определяет объект-продукт, создаваемый соответствующей конкретной фабрикой; реализует интерфейс Abstract Product;
  5. Client клиент: пользуется исключительно интерфейсами, которые объявлены в классах AbstractFactory и AbstractProduct.

Отношения

  1. Обычно во время выполнения создается единственный экземпляр класса ConcreteFactory. Эта конкретная фабрика создает объекты-продукты, имеющие вполне определенную реализацию.
  2. Для создания других видов объектов клиент должен воспользоваться другой конкретной фабрикой;
  3. AbstractFactory передоверяет создание объектов-продуктов своему подклассу ConcreteFactory

Результаты

Паттерн абстрактная фабрика обладает следующими плюсами и минусами:
1) Изолирует конкретные классы. Помогает контролировать классы объектов, создаваемых приложением. Поскольку фабрика инкапсулирует ответственность за создание классов и сам процесс их создания, то она изолирует клиента от деталей реализации классов. Клиенты манипулируют экземплярами через их абстрактные интерфейсы.
Имена изготавливаемых классов известны только конкретной фабрике, в коде клиента они не упоминаются;

2) Упрощает замену семейств продуктов. Класс конкретной фабрики появляется в приложении только один раз: при инстанцировании. Это облегчает замену используемой приложением конкретной фабрики. Приложение может
изменить конфигурацию продуктов, просто подставив новую конкретную
фабрику.
Поскольку абстрактная фабрика создает все семейство продуктов, то и заменяется сразу все семейство. В нашем примере пользовательского
интерфейса перейти от виджетов Motif к виджетам Presentation Manager можно, просто переключившись на продукты соответствующей фабрики и заново создав интерфейс;

3) Гарантирует сочетаемость продуктов. Если продукты некоторого семейства спроектированы для совместного использования, то важно, чтобы приложение в каждый момент времени работало только с продуктами единственного семейства. Класс AbstractFactory позволяет легко соблюсти это ограничение;

[минус] 4) Поддержать новый вид продуктов трудно. Расширение абстрактной фабрики для изготовления новых видов продуктов - непростая задача. Интерфейс AbstractFactory фиксирует набор продуктов, которые можно создать. Для поддержки новых продуктов необходимо расширить интерфейс фабрики, то есть изменить класс AbstractFactory и все его подклассы. Решение этой проблемы посмотрим в разделе «Реализация».

Реализация

Полезные приёмы, которые можно применять, когда реализуешь данный паттерн:

  1. конкретная фабрика для данного семейства обычно существует в единственном экземпляре - так что неплохо было бы для неё обратиться к паттерну "Одиночка"
  2. Если семейств продуктов много то имеет смысл обратиться к паттерну "Прототип"
  3. Определение расширяемых фабрик - об этой проблеме мы упоминали выше - как сделать фабрику расширяемой - то есть обеспечить возможность добавить новый вид продукта во все семейства-сборки.

Пример кода

Предлагаю к изучению в вот такой вот замечательный пример кода Абстрактной фабрики на PHP

Известные применения

В библиотеке ЕТ++ [WGM88] паттерн абстрактная фабрика применяется для достижения переносимости между разными оконными системами (например, XWindows и SunView).
Абстрактный базовый класс WindowSystem определяет интерфейс для создания объектов, которое представляют ресурсы оконной системы
(MakeWindow, MakeFont, MakeColor и т.п.).
Его конкретные подклассы реализуют эти интерфейсы для той или иной оконной системы. Во время выполнения ЕТ++ создает экземпляр конкретного подкласса WindowSystem, который уже
и порождает объекты, соответствующие ресурсам данной оконной системы.

Родственные паттерны

Классы Abstract Factory часто реализуются фабричными методами , но могут быть реализованы и с помощью паттерна прототип.

Конкретная фабрика часто описывается паттерном одиночка.

Читайте дальше

Дальше читайте о замечательном шаблоне "Строитель"