Design Patterns — Abstract Factory.

Шаблон проектирования Фабрика — краткое руководство.

Efim Sirotkin
Clean Code

--

В этом небольшом руководстве я раскрыл несколько секретов по быстрому освоению одного из популярных шаблонов проектирования — Абстрактная Фабрика. В примерах кода буду использовать C++, но только из-за того, что мне удобнее с ним работать. При желании шаблон можно настроить под программирование на Java, Python, C#, JavaScript и прочие.

Абстрактная фабрика нацелена на использование в шаблонах создания интерфейса, где требуется инициировать многочисленные объекты и классы. Если точнее, она определяет более эффективное использование наследования (шаблонов создания классов) и делегирования (шаблонов создания объектов).

Курс разработки сетевых приложений на Golang

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

Время объединить понятие фабрики и шаблонов проектирования. Использовать Абстрактную Фабрику целесообразно, когда появляется нужда создать несколько зависимых объектов без обязательного присвоения конкретных классов. При этом есть желание инкапсулировать формирование продуктов посредством наследования.

Шаг 1: ключевые слова

Один из секретов быстрого освоения шаблона проектирования — понимание различий между всеми элементами производства фабрики. Столь простой способ мне помог разобраться с понятиями фабрики, зафиксировать их в голове и определиться в чём её отличия от прочих шаблонов проектирования.

Ключевые слова:

· Продукт — это объект, изготовленный на фабрике, который относится к целому семейству аналогичных элементов. Специфика продукта заключается в отсутствии абстракции. Для примера: BMWdoorHandle, FordDoorHandle.

· Абстрактный продукт — находится на уровень выше стандартного представления о продукции. Им можно назвать всё семейство. Пример: DoorHandle, DoorWindow.

· Фабрика на «физическом» уровне управляет формированием и окончательной доработкой продукта. Приблизительный вид: BMWFactory, FordFactory.

· Абстрактная фабрика — это интерфейс для создания семейств взаимозависимых или связанных элементов, но без указания классов. Пример: CarFactory.

Шаг 2: Диаграмма

Во время рассмотрения Абстрактной Фабрики важно оперировать выше описанными ключевыми словами. Если в коде появляется расхождение с базовым представлением о шаблоне, скорее всего что-то получилось неправильно. Стоит для примера рассмотреть Конкретную Фабрику, которая является наследующим звеном от Абстрактной Фабрики. В это же время Конкретный Продукт — наследует класс Абстрактной Продукции. Звучит всё настолько же просто, насколько и выглядит.

В диаграмме оба конкретных класса наследуются от абстрактных классов. Фабрика выполняет всю грязную работу и выпускает конкретную продукцию (ProductA и ProductB). Теперь должно стать понятнее, что картинку можно значительно усложнить, добавив массу конкретных фабрик и разновидностей продуктов. Диаграмма может многократно расширяться, но только вширь, а не в высоту.

Шаг 3: Пример кода

Я предлагаю взять класс за классом из кода в репозитории GitHub. Всё содержимое — вставить в один из онлайн-редакторов C++. Чтобы долго не искать, вот примеры c++shell, jdoodle, onlineGDB. Теперь время запустить код и посмотреть на его результат. В качестве подсказки я оставлю заметки и небольшое описание ниже. В примерах использую понятные имена уже используемых классов, а в комментариях оставляю связанные с ним ключевые слова.

Абстрактный продукт

Это класс, который является определяющим звеном для всего семейства продукции, наследующейся от него. В конкретном примере используется абстрактный продукт a DoorHandle. Для демонстрации в отрывок кода ещё добавил функцию вывода.

Продукт

В текущем виде — это ручка от дверей Ford и BMW. У каждой детали авто есть собственный серийный номер. Продукт может выдать свой уникальный номер запчасти. Ещё в пример мог бы вставить окна дверей (DoorWindow) или руль (SteeringWheel). В этом случае классы дескриптора наследуются от абстрактного класса из примера выше.

Абстрактная фабрика

Представляет собой общий (абстрактный) класс, который включает в себя только создающую функцию create. Фабрика действительно только лишь создаёт продукты.

Конкретная фабрика

Отдельная фабрика, своего рода цех, посвящённый производству одного продукта. Это трудолюбивый класс, который отвечает за решение головоломок. В примере каждый продукт уникален, поэтому изготавливаются отдельные запчасти для BMW и отдельные — для Ford. Главная задача конкретной фабрики заключается в возврате продукта для конкретного бренда. Опять же, ничего не мешает мне создать класс BMWDoorWindow с новой функцией, возвращающей экземпляр для данного продукта. Я уже реализовал подобную возможность, она доступна по ссылке на репозиторий GitHub.

Основная функция

Является последней частью кода, которая доступна для запуска со стороны клиента. Любой «заказчик» может легко найти и купить подходящую ему продукцию для любых личных целей.

Курс разработки сетевых приложений на Golang

На первый взгляд преимущества можно не заметить. Чтобы лучше понять достоинство шаблона, стоит представить базу из тысячи или сотен тысяч запчастей для десятков марок автомобилей разных годов выпуска. Сложно вообразить хаос, который появляется при использовании плохо разработанного кода во время каждой покупки дверной ручки клиентом. Если захотят сменить сидения или модернизировать двигатель, база просто зависнет. Всё ещё проблема кажется несущественной? Всё это можно умножить на 10, 20 или 100, так как на фабриках часто производят запчасти для разных брендов автомобилей.

Абстрактная Фабрика обеспечивает простой подход и улучшает ремонтопригодность кода. Шаблон обеспечивает настолько элементарный подход, что даже начинающий разработчик сможет без труда создать, удалить один или несколько продуктов.

Абстрактная Фабрика — всего лишь начало пути. Он является одним из самых используемых шаблонов проектирования, но всё же редко применяется сам по себе. Обычно к нему прибегают в сочетании с другими шаблонами проектирования.

Источник: medium

--

--