Порождающие шаблоны / Строитель
- Описание паттерна
- Реализация паттерна
- Примеры
- Использование
- Преимущества
- Недостатки
- Похожие паттерны
- Взаимодействие с другими паттернами
- Источники
Представьте, что вы продаете компьютеры - уже собранные, полностью функционирующие. К вам приходят заказчики, высказывают свои пожелания, а вы на их основе комплектуете все необходимое.
Заказы могут быть самые разные:
- дополнительный монитор или даже два
- без звуковой карты
- с джойстиком
- нестандартная клавиатура
- и т. д.
То есть настройка каждого узла может быть довольно тонкой. Кажется, пора это все выделять в отдельный класс.
Строитель - это более сложная Фабрика
. Если Фабрика
просто выбирает нужный подкласс объектов в зависимости от параметров, строитель может осуществлять более тонкую настройку, например, использовать разные алгоритмы сборки объекта. В результате, на выходе могут получаться совершенно разные объекты одного и того же подкласса.
Паттерн инкапсулирует процесс создания сложных объектов: скрывает сложные детали создания и позволяет изменять внутреннее представление объектов. Внутри строителя вы имеете полный контроль над каждым шагом создания объекта.
Строитель
даёт возможность использовать один и тот же код строительства для получения разных представлений объектов. Он разбивает создание объекта на несколько этапов вместо того, чтобы делать это сразу в конструкторе.
При этом разные строители могут выполнять одну и ту же задачу, с одними и теми же параметрами по-разному. Например:
- один сделает вам стандартный ПК, а другой - моноблок
- один использует процессоры Intel, а второй - AMD
- один собирает компьютер из комплектующих, а второй описывает эти комплектующие в мануале
Конечные продукты функционально очень похожи, клиент может ими пользоваться, но тем не менее они разные.
Вы всегда можете добавить в программу нового Строителя
, чтобы получать новый тип продукта.
Если процесс строительства довольно сложен (имеется определенная последовательность шагов или разные способы осуществления операций), вы можете инкапсулировать и его. Вместо того, чтобы вызывать методы Строителя
прямо из клиентского кода, создайте класс Директора
, который будет делать это за вас - ему только нужно передать экземпляр Строителя
.
Обычно конечный результат работы вы будете получать от самих строителей, а не от директора, чтобы не привязывать его к конкретным классам строителей (у которых может быть разный интерфейс метода получения результата getComputer
, getManual
).
- Строители
- Интерфейс
Builder
определяет методы сборки объекта - Классы конкретных строителей
ConcreteBuilder
реализуют эти методы
- Интерфейс
Director
руководит процессом сборки объектов- Клиентский код просто выбирает
КонкретногоСтроителя
, передает егоДиректору
и получает готовый продукт.
- Конструктор вашего класса стал слишком громоздким, так как приходится передавать много параметров для настройки.
- Требуется создавать разные представления одного и того же функционала (ПК и моноблок).
- Нужно производить сложные объекты, например, рекурсивные (деревья Компоновщика). Или такие, производство которых можно разделить на несколько шагов.
- Возможно пошаговое создание продуктов
- Можно изменять представление продукта
- Изоляция сложного кода сборки
- Введение дополнительных классов
- Если у
Строителей
нет общего метода получения результата, то клиент привязан к интерфейсу разныхСтроителей
.
- Фабричный метод (Factory method). Простой выбор нужного подкласса (без настройки).
- Абстрактная фабрика (Abstract factory). Фабрика фабрик.
Строитель часто является эволюцией паттерна Фабричный метод
.
Способы реализации паттерна (вариации механизмов работы паттерна)
- Мост (Bridge). Строитель может быть оформлен в виде
Моста
, гдеДиректор
- абстракция, аСтроители
- реализации. - Одиночка (Singleton).
Строитель
может бытьСинглтоном
.
Частое применение (паттерны не связаны напрямую)
- Компоновщик (Composite).
Строитель
пошагово сооружает деревоКомпоновщика
.