Что такое паттерн фабрика

Сравнение фабрик

В этой статье мы попробуем разобраться чем отличаются:

Во многих книгах и источниках определения «фабрик» даётся авторами по-своему. Это создаёт большую путаницу при чтении материалов в интернете.

Итак, давайте разберёмся в вариациях фабрик, чтобы раз и навсегда понять разницу между ними.

1. Фабрика

Фабрика — это общая концепция проектирования функций, методов и классов, когда какая-то одна часть программы отвечает за создание других частей программы.

Вы можете услышать слово Фабрика от других людей, когда они имеют в виду:

То, что человек имеет в виду, произнося Фабрика, проще всего понять из контекста, мы сейчас рассмотрим все вариации.

2. Создающий метод

Создающий метод Определён в книге Refactoring To Patterns. — это простой метод-обёртка над вызовом конструктора продукта. Выделив создающий метод, вы изолируете любые изменения в конструировании продуктов от основного кода. Например, вы можете вовсе убрать вызов конструктора из создающего метода, отдавая вместо нового какой-то существующий объект.

Многие называют его фабричным методом, только потому, что он создаёт новые объекты. Типичная логика: «этот метод создаёт объекты, а раз все фабрики создают что-то, значит этот метод — фабричный». И это вносит основную путаницу между понятием Создающего метода и паттерном Фабричный метод.

В этом примере, метод next является создающим методом:

3. Статический фабричный метод

Требуется создать разные по функциональности конструкторы, у которых бы совпадали сигнатуры (например, Random(int max) и Random(int min) ). Это невозможно во многих языках программирования, но создав статический метод, вы можете обойти это ограничение.

Хочется повторно использовать готовые объекты, вместо создания новых (например, паттерн Одиночка). При вызове конструктора вы всегда создаёте новый объект. Это можно обойти, если вынести вызов конструктора в новый метод. В этом методе вы можете сначала поискать готовый объект в каком-то кеше, и только если его нет, создать новый объект.

В следующем примере, метод load является статическим фабричным методом — он предоставляет удобный способ загрузить пользователя из базы данных.

4. Паттерн Простая фабрика

Паттерн Простая фабрика Определён в книге Head First Design Patterns. — это класс, в котором есть один метод с большим условным оператором, выбирающим создаваемый продукт. Этот метод вызывают с неким параметром, по которому определяется какой из продуктов нужно создать. У простой фабрики, обычно, нет подклассов.

Обычно, простую фабрику путают с общим понятием Фабрики или с любым из фабричных паттернов.

Если объявить класс простой фабрики абстрактным (Java, C#), это не сделает его одним и тем же, что и абстрактная фабрика!

Вот пример простой фабрики:

Простая фабрика находится в шаге от того, чтобы стать Фабричным методом.

5. Паттерн Фабричный метод

Паттерн Фабричный метод Определён в книге «банды четырёх» Design Patterns: Elements of Reusable Object-Oriented Software. — это устройство классов, при котором подклассы могут переопределять тип создаваемого в суперклассе продукта.

Если вы имеете иерархию продуктов и абстрактный создающий метод, который переопределяется в подклассах, то перед вами паттерн Фабричный метод.

6. Паттерн Абстрактная фабрика

Паттерн Абстрактная фабрика Определён в книге «банды четырёх» Design Patterns: Elements of Reusable Object-Oriented Software. — это устройство классов, облегчающее создание семейств продуктов.

Если у вас нет семейств продуктов, значит не может быть и абстрактной фабрики.

Послесловие

Теперь, когда вы окончательно разобрались в терминологии, почитайте наши описания фабричных паттернов:

Источник

Шаблоны проектирования простым языком. Часть первая. Порождающие шаблоны

Авторизуйтесь

Шаблоны проектирования простым языком. Часть первая. Порождающие шаблоны

Шаблоны проектирования — это руководства по решению повторяющихся проблем. Это не классы, пакеты или библиотеки, которые можно было бы подключить к вашему приложению и сидеть в ожидании чуда. Они скорее являются методиками, как решать определенные проблемы в определенных ситуациях.

Википедия описывает их следующим образом:

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

Будьте осторожны

Также заметьте, что примеры ниже написаны на PHP 7. Но это не должно вас останавливать, ведь принципы остаются такими же.

Типы шаблонов

Шаблоны бывают следующих трех видов:

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

Порождающие шаблоны — шаблоны проектирования, которые абстрагируют процесс инстанцирования. Они позволяют сделать систему независимой от способа создания, композиции и представления объектов. Шаблон, порождающий классы, использует наследование, чтобы изменять наследуемый класс, а шаблон, порождающий объекты, делегирует инстанцирование другому объекту.

Существуют следующие порождающие шаблоны:

Простая фабрика (Simple Factory)

В объектно-ориентированном программировании (ООП), фабрика — это объект для создания других объектов. Формально фабрика — это функция или метод, который возвращает объекты изменяющегося прототипа или класса из некоторого вызова метода, который считается «новым».

Пример из жизни: Представьте, что вам надо построить дом, и вам нужны двери. Было бы глупо каждый раз, когда вам нужны двери, надевать вашу столярную форму и начинать делать дверь. Вместо этого вы делаете её на фабрике.

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

Перейдем к коду. У нас есть интерфейс Door и его реализация:

И затем мы можем использовать всё это:

Когда использовать: Когда создание объекта — это не просто несколько присвоений, а какая-то логика, тогда имеет смысл создать отдельную фабрику вместо повторения одного и того же кода повсюду.

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

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

Пример из жизни: Рассмотрим пример с менеджером по найму. Невозможно одному человеку провести собеседования со всеми кандидатами на все вакансии. В зависимости от вакансии он должен распределить этапы собеседования между разными людьми.

Простыми словами: Менеджер предоставляет способ делегирования логики создания экземпляра дочерним классам.

17–19 декабря, Онлайн, Беcплатно

Перейдём к коду. Рассмотрим приведенный выше пример про HR-менеджера. Изначально у нас есть интерфейс Interviewer и несколько реализаций для него:

Читайте также:  Что требуется для переоформления автомобиля в гаи 2021

Теперь создадим нашего HiringManager :

И теперь любой дочерний класс может расширять его и предоставлять необходимого интервьюера:

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

Абстрактная фабрика (Abstract Factory)

Абстрактная фабрика — порождающий шаблон проектирования, предоставляет интерфейс для создания семейств взаимосвязанных или взаимозависимых объектов, не специфицируя их конкретных классов. Шаблон реализуется созданием абстрактного класса Factory, который представляет собой интерфейс для создания компонентов системы (например, для оконного интерфейса он может создавать окна и кнопки). Затем пишутся классы, реализующие этот интерфейс.

Пример из жизни: Расширим наш пример про двери из простой фабрики. В зависимости от ваших нужд вам понадобится деревянная дверь из одного магазина, железная дверь — из другого или пластиковая — из третьего. Кроме того, вам понадобится соответствующий специалист: столяр для деревянной двери, сварщик для железной двери и так далее. Как вы можете заметить, тут есть зависимость между дверьми.

Простыми словами: Фабрика фабрик. Фабрика, которая группирует индивидуальные, но связанные/зависимые фабрики без указания их конкретных классов.

Обратимся к коду. Используем пример про двери. Сначала у нас есть интерфейс Door и несколько его реализаций:

Затем у нас есть несколько DoorFittingExpert для каждого типа дверей:

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

Когда использовать: Когда есть взаимосвязанные зависимости с не очень простой логикой создания.

Строитель (Builder)

Строитель — порождающий шаблон проектирования, который предоставляет способ создания составного объекта. Предназначен для решения проблемы антипаттерна «Телескопический конструктор».

Пример из жизни: Представьте, что вы пришли в McDonalds и заказали конкретный продукт, например, БигМак, и вам готовят его без лишних вопросов. Это пример простой фабрики. Но есть случаи, когда логика создания может включать в себя больше шагов. Например, вы хотите индивидуальный сэндвич в Subway: у вас есть несколько вариантов того, как он будет сделан. Какой хлеб вы хотите? Какие соусы использовать? Какой сыр? В таких случаях на помощь приходит шаблон «Строитель».

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

Давайте я покажу на примере, что такое «Телескопический конструктор». Когда-то мы все видели конструктор вроде такого:

Как вы можете заметить, количество параметров конструктора может резко увеличиться, и станет сложно понимать расположение параметров. Кроме того, этот список параметров будет продолжать расти, если вы захотите добавить новые варианты. Это и есть «Телескопический конструктор».

Затем мы берём «Строителя»:

Когда использовать: Когда может быть несколько видов объекта и надо избежать «телескопического конструктора». Главное отличие от «фабрики» — это то, что она используется, когда создание занимает один шаг, а «строитель» применяется при множестве шагов.

Прототип (Prototype)

Задаёт виды создаваемых объектов с помощью экземпляра-прототипа и создаёт новые объекты путём копирования этого прототипа. Он позволяет уйти от реализации и позволяет следовать принципу «программирование через интерфейсы». В качестве возвращающего типа указывается интерфейс / абстрактный класс на вершине иерархии, а классы-наследники могут подставить туда наследника, реализующего этот тип.

Пример из жизни: Помните Долли? Овечка, которая была клонирована. Не будем углубляться, главное — это то, что здесь все вращается вокруг клонирования.

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

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

Обратимся к коду. В PHP это может быть легко реализовано с использованием clone :

Затем он может быть клонирован следующим образом:

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

Когда использовать: Когда необходим объект, похожий на существующий объект, либо когда создание будет дороже клонирования.

Одиночка (Singleton)

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

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

Простыми словами: Обеспечивает тот факт, что создаваемый объект является единственным объектом своего класса.

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

Прим. перев. Подробнее о подводных камнях шаблона одиночка читайте в нашей статье.

Перейдем к коду. Чтобы создать одиночку, сделайте конструктор приватным, отключите клонирование и расширение и создайте статическую переменную для хранения экземпляра:

Источник

Зачем нужен паттерн Factory (Фабрика)?

Давайте представим, что нам нужен класс, который создает объекты разного типа. Иногда это очень удобно. Почему?

Во-первых, представим, что нам нужна «фабрика», которая выпускает разные пончики:

Соответственно, под каждый пончик должен быть свой класс.

Однако все эти классы очень похожи. Все пончики будут иметь одинаковый набор параметров:

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

То есть мы сможем просто сказать:

Для этого нам необходимо использовать паттерн Factory. Ну, что ж, давайте попробуем создать нашу первую «фабрику» (Factory). Давайте назовем ее «Фабрика пончиков» (DoughnutFactory):

Отлично! Теперь давайте создадим три класса пончиков, которые имплементиуют интерфейс Doughnut.

Итак, суть фабрики сводится к тому, чтобы производить объекты разного типа. Но как сделать так, чтоб Фабрика понимала какой именно тип объекта(пончика) мы хотим получить: с вишней, с белым шоколадом или с миндалем?

Читайте также:  к каким лесам относятся леса расположенные на землях не относящихся к землям лесного фонда

Для этого давайте создадим ENUM, в котором запишем все возможные типы пончиков:

Таким образом, наша фабрика будет принимать название объекта (в нашем случае ENUM), и возвращать объект нужного типа. Прототип такой функции будет выглядеть следующим образом:

Как видите, принимается ENUM DoughnutTypes, а возвращается любой объект, имплементирующий интерфейс Doughnut. Таким образом, мы теперь можем «конструировать» любой пончик и возвращать его пользователю.

Итак, перейдем к сути. Определяем тип с помощью обычного switch. case:

Как Вы видите, мы создаем и возвращаем новый объект нужного типа. Если будет введено не CHERRY, не CHOCOLATE и не ALMOND (а это может быть только null), тогда мы показываем ошибку.

Хорошо, теперь протестируем наш код. Создадим main(), в котором создадим все типы поисков по очереди и вызовем на них метод eat():

Отлично! Вот мы и создали свою первую фабрику.

Какие преимущества дает паттерн Фабрика (Factory)

Благодаря паттерну Factory наша жизнь облегчается:

1. Во-первых, мы можем создавать объекты разных типов с помощью одного и того же метода. Это очень удобно, когда возникает ситуация, в которой мы не знаем, какой тип нам понадобится.

Для убедительности, можно запустить метод eatRandomDoughnut() сто раз:

В итоге получим что-то наподобие:

2. Во-вторых, мы можем «запаковать» дополнительный функционал в нашу Фабрику. Например, посчитаем, сколько пончиков каждого типа было создано конкретной фабрикой.

Сначала создаем новые переменные, которые будут хранить результат:

Отлично! Для вывода результатов в консоль напишем следущий метод:

Итого, наш класс DoughnutFactory целиком, со всеми дополнениями, будет выглядеть так:

Отлично! Теперь запустим с помощью такого кода:

В консоли получим что-то похожее на это:

Согласитесь, считать с помощью Фабрики гораздо удобнее чем, например, создавать статические переменные в каждом классе, а помочь печатать их с помощью отдельного метода. Это и читабельнее, и будет легче править в будущем.

Конечно, это очень простой пример. Вы можете добавлять любой другой функционал.

3. И в-третьих, с помощью паттерна Factory мы можем генерировать сложные объекты намного проще и с меньшим количеством ошибок.

Например, у нас есть объект с огромным количеством полей:

Таким образом, при создании сложных объектов, мы можем «прятать» весь этот процесс в фабрику. Например, если для создания объекта требуются какие-нибудь сложные вычисления, или если у объекта очень много параметров, а Вам пока нужен только объект с параметрами по умолчанию.

Как видите, у паттерну Фабрика очень много полезных применений. И теперь Вы знаете, как создать свою собственную.

Надеемся, что наша статья была Вам полезна. Можно записаться к нам на курсы по Java на сайте.

Источник

Абстрактная фабрика на пальцах

Написать данную статью меня заставили две причины. Совсем недавно я познакомился с паттерном Абстрактная фабрика. Как говорится – «Не умеешь сам, научи товарища». Известно, что один из лучших способов закрепления материала – это объяснение кому-либо ранее изученного. Вторая причина – в процессе изучения данного паттерна я не встретил материала, который лично для меня излагал бы вполне ясно суть Абстрактной фабрики (по крайней мере на Хабре).

Итак, приступим. Самый первый вопрос, на который нужно ответить самому себе, изучая данный паттерн: «Что же такое Абстрактная фабрика». Самый простой и точный ответ, гласит, что Абстрактная фабрика – это «фабрика фабрик». Но здесь появляется второй вопрос: «Для чего вообще может кому-нибудь понадобиться «фабрика фабрик»? Чтобы на него ответить рассмотрим пример из реальной жизни.

Допустим, вы решили полностью взять под свой контроль рынок автомобилей. Как это сделать? Вы можете создать свою марку автомобиля, своё производство, провести масштабную рекламную компанию и т.д. Но, в этом случае вам придётся сражаться с такими гигантами авторынка, как Toyota или Ford. Не факт, что из данной борьбы вы выйдите победителем. Гораздо лучшим решением будет скупить заводы всех этих компаний, продолжить выпускать автомобили под их собственными марками, а прибыль класть себе в карман. Если я не ошибаюсь, такая структура в экономике называется – холдинг. Вот этот холдинг и будет Абстрактной фабрикой или «фабрикой фабрик». В нашей программе Абстрактная фабрика (холдинг) будет представлена интерфейсом или абстрактным классом. Предприятия, входящие в холдинг, представлены классами, реализующими данный интерфейс.

Далее, вы собираете управляющих вашими фабриками и говорите: «Отныне на наших фабриках мы будем делать автомобили с 2 типами кузова – седан и купе. Например, японцы будут делать ToyotaSedan и ToyotaCoupe, американцы — FordSedan и FordCoupe». А чтобы на фабриках не забыли, что именно нужно производить, и не начали делать, например, внедорожники, повесим общие чертежи седана и купе в офисе нашего холдинга на самом видном месте (на конкретной фабрике инженеры сами разберутся как именно им делать нужные автомобили). Таким образом, в нашем интерфейсе CarsFactory появляются 2 метода:

Соответственно, в дочерних классах интерфейса CarsFactory, данные методы тоже должны быть реализованы.

Обратите внимание, что типом возвращаемого значения в методах будет являться именно общий для возвращаемых значений тип – sedan и coupe. Возвращаясь к нашей аналогии — вы сказали фабрике сделать седан – вам сделали седан. Особенности, например, седана марки Ford, вас не интересуют.

Как несложно догадаться из приведённого кода, у нас в программе должны появится некие сущности, описывающие конкретные типы кузова – седан и купе. Такими сущностями будут интерфейсы.

Ну и конечно же, данные чертежи должны иметь конкретное воплощение в виде автомобилей, создаваемых на той или иной фабрике.

Но как будет взаимодействовать конкретный пользователь (покупатель автомобиля) с нашим холдингом? Покупатель вообще знать не знает о том, что вы захватили все фабрики мира по производству автомобилей. Он приходит в маленький скромный офис холдинга и говорит: «Мне нужен автомобиль!» «Отлично!» — говорим мы ему, — «вы обратились по адресу! Фабрика фабрик – это то, что вам нужно!»

«Автомобили какой фирмы предпочитаете в данное время суток?», — спрашиваем мы. Допустим, покупатель хочет приобрести тойоту. Нет проблем!

«А какой тип кузова вы бы хотели?» Допустим – седан. «Прекрасный выбор!»

Источник

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

Абстрактная фабрика — это порождающий паттерн проектирования, который позволяет создавать семейства связанных объектов, не привязываясь к конкретным классам создаваемых объектов.

Читайте также:  Что такое период оттепели

Представьте, что вы пишете симулятор мебельного магазина. Ваш код содержит:

Семейства продуктов и их вариации.

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

Клиенты расстраиваются, если получают несочетающиеся продукты.

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

Все вариации одного и того же объекта должны жить в одной иерархии классов.

Конкретные фабрики соответствуют определённой вариации семейства продуктов.

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

Для клиентского кода должно быть безразлично, с какой фабрикой работать.

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

Осталось прояснить последний момент: кто создаёт объекты конкретных фабрик, если клиентский код работает только с интерфейсами фабрик? Обычно программа создаёт конкретный объект фабрики при запуске, причём тип фабрики выбирается, исходя из параметров окружения или конфигурации.

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

Конкретные продукты — большой набор классов, которые относятся к различным абстрактным продуктам (кресло/столик), но имеют одни и те же вариации (Викторианский/Модерн).

Абстрактная фабрика объявляет методы создания различных абстрактных продуктов (кресло/столик).

Конкретные фабрики относятся каждая к своей вариации продуктов (Викторианский/Модерн) и реализуют методы абстрактной фабрики, позволяя создавать все продукты определённой вариации.

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

В этом примере Абстрактная фабрика создаёт кросс-платформенные элементы интерфейса и следит за тем, чтобы они соответствовали выбранной операционной системе.

Пример кросс-платформенного графического интерфейса пользователя.

Кросс-платформенная программа может показывать одни и те же элементы интерфейса, выглядящие чуточку по-другому в различных операционных системах. В такой программе важно, чтобы все создаваемые элементы всегда соответствовали текущей операционной системе. Вы бы не хотели, чтобы программа, запущенная на Windows, вдруг начала показывать чекбоксы в стиле macOS.

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

В самом начале программа определяет, какая из фабрик соответствует текущей операционке. Затем создаёт эту фабрику и отдаёт её клиентскому коду. В дальнейшем клиент будет работать только с этой фабрикой, чтобы исключить несовместимость возвращаемых продуктов.

Клиентский код не зависит от конкретных классов фабрик и элементов интерфейса. Он общается с ними через абстрактные интерфейсы. Благодаря этому клиент может работать с любой разновидностью фабрик и элементов интерфейса.

Чтобы добавить в программу новую вариацию элементов (например, для поддержки Linux), вам не нужно трогать клиентский код. Достаточно создать ещё одну фабрику, производящую эти элементы.

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

Абстрактная фабрика скрывает от клиентского кода подробности того, как и какие конкретно объекты будут созданы. Но при этом клиентский код может работать со всеми типами создаваемых продуктов, поскольку их общий интерфейс был заранее определён.

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

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

Создайте таблицу соотношений типов продуктов к вариациям семейств продуктов.

Сведите все вариации продуктов к общим интерфейсам.

Определите интерфейс абстрактной фабрики. Он должен иметь фабричные методы для создания каждого из типов продуктов.

Создайте классы конкретных фабрик, реализовав интерфейс абстрактной фабрики. Этих классов должно быть столько же, сколько и вариаций семейств продуктов.

Измените код инициализации программы так, чтобы она создавала определённую фабрику и передавала её в клиентский код.

Замените в клиентском коде участки создания продуктов через конструктор вызовами соответствующих методов фабрики.

    Гарантирует сочетаемость создаваемых продуктов. Избавляет клиентский код от привязки к конкретным классам продуктов. Выделяет код производства продуктов в одно место, упрощая поддержку кода. Упрощает добавление новых продуктов в программу. Реализует принцип открытости/закрытости.
    Усложняет код программы из-за введения множества дополнительных классов. Требует наличия всех типов продуктов в каждой вариации.

Многие архитектуры начинаются с применения Фабричного метода (более простого и расширяемого через подклассы) и эволюционируют в сторону Абстрактной фабрики, Прототипа или Строителя (более гибких, но и более сложных).

Строитель концентрируется на построении сложных объектов шаг за шагом. Абстрактная фабрика специализируется на создании семейств связанных продуктов. Строитель возвращает продукт только после выполнения всех шагов, а Абстрактная фабрика возвращает продукт сразу же.

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

Абстрактная фабрика может быть использована вместо Фасада для того, чтобы скрыть платформо-зависимые классы.

Абстрактная фабрика может работать совместно с Мостом. Это особенно полезно, если у вас есть абстракции, которые могут работать только с некоторыми из реализаций. В этом случае фабрика будет определять типы создаваемых абстракций и реализаций.

Не втыкай в транспорте

Лучше почитай нашу книгу о паттернах проектирования.

Теперь это удобно делать даже во время поездок в общественном транспорте.

Эта статья является частью нашей электронной книги Погружение в Паттерны Проектирования.

Источник

Сайт для любознательных читателей