Паттерн Строитель (Builder) — это порождающий шаблон проектирования, который используется для поэтапного создания сложных объектов. Строитель особенно полезен, когда процесс создания объекта требует нескольких шагов или состоит из множества опциональных компонентов, которые не всегда нужны. В этом случае паттерн помогает избежать длинных конструкторов и создать объект в определённой конфигурации, сохраняя при этом гибкость настройки.
Паттерн Строитель простыми словами
Паттерн Строитель — это способ создания сложных объектов шаг за шагом. Представьте, что вы строите что-то с помощью конструктора: сначала собираете основу, затем добавляете детали, и в конце получается готовое изделие. Так же и здесь, с помощью паттерна Строитель можно поэтапно собирать объект, выбирая только нужные части.
Представьте, что вы заказываете бургер, и хотите добавить в него только определенные ингредиенты (например, котлету, салат, сыр и соус). Вместо того чтобы каждый раз выбирать все заново, вы задаете параметры, и повар собирает бургер именно так, как вам нужно.
В программировании паттерн Строитель помогает создать объект по частям, задавая нужные параметры, а не создавая его сразу со всеми возможными элементами, которые могут быть лишними.
Основные идеи паттерна Строитель
- Разделение создания объекта и его представления: процесс сборки объекта отделяется от его структуры, что позволяет создавать различные представления одного и того же объекта.
- Гибкость в конфигурации: можно легко менять параметры создаваемого объекта, не изменяя его основной класс.
- Пошаговое создание: объект можно строить поэтапно, добавляя нужные компоненты постепенно.
Структура паттерна Строитель
- Product (Продукт) — объект, который требуется создать. Например, дом, автомобиль или сложный отчет.
- Builder (Строитель) — интерфейс, определяющий шаги для сборки продукта. Например, методы для создания стен, окон, дверей и крыши для дома.
- ConcreteBuilder (Конкретный строитель) — конкретная реализация Builder, которая собирает объект, следуя шагам, и сохраняет частичный результат.
- Director (Директор) — объект, который контролирует процесс создания объекта, используя методы Builder. Директор обычно задаёт порядок сборки, оставляя пользователю возможность гибкой настройки.
Преимущества
- Упрощает создание сложных объектов.
- Позволяет избежать громоздких конструкторов.
- Делает код более читаемым и поддерживаемым.
- Упрощает создание разных конфигураций одного и того же объекта.
Недостатки
- Увеличивает количество классов.
- Усложняет код, если объект простой и не требует поэтапной сборки.
Когда использовать
- Когда объект имеет много параметров, и часть из них опциональна.
- Когда порядок создания или инициализации параметров важен.
- Когда нужно создать разные представления одного и того же объекта.
Паттерн Строитель широко используется в ситуациях, где требуются разные версии одного и того же объекта, и нужно обеспечить гибкость создания.
Пример использования
В Swift паттерн Строитель может быть полезен для создания объектов с множеством опциональных параметров. Например, можно представить создание объекта Burger
, который может содержать различные ингредиенты (котлету, сыр, соус, салат и т.д.), и каждый из них — необязательный.
Вот пример реализации паттерна Строитель для класса Burger
в Swift:
// Класс продукта, который мы собираем class Burger { var hasCheese: Bool var hasLettuce: Bool var hasTomato: Bool var hasPickles: Bool // Закрытый инициализатор, доступный только для билдера private init(builder: BurgerBuilder) { self.hasCheese = builder.hasCheese self.hasLettuce = builder.hasLettuce self.hasTomato = builder.hasTomato self.hasPickles = builder.hasPickles } func description() { print("Ваш бургер содержит: ") if hasCheese { print("Сыр") } if hasLettuce { print("Салат") } if hasTomato { print("Помидоры") } if hasPickles { print("Огурцы") } } } // Билдер для создания объекта Burger class BurgerBuilder { var hasCheese = false var hasLettuce = false var hasTomato = false var hasPickles = false func addCheese() -> BurgerBuilder { self.hasCheese = true return self } func addLettuce() -> BurgerBuilder { self.hasLettuce = true return self } func addTomato() -> BurgerBuilder { self.hasTomato = true return self } func addPickles() -> BurgerBuilder { self.hasPickles = true return self } // Метод, который возвращает готовый объект Burger func build() -> Burger { return Burger(builder: self) } } // Пример использования let burger = BurgerBuilder() .addCheese() .addLettuce() .addTomato() .build() burger.description()
Объяснение кода
- Burger — это класс, который представляет собой конечный продукт. Он имеет различные свойства (например,
hasCheese
,hasLettuce
и т.д.), и инициализируется только черезBurgerBuilder
. - BurgerBuilder — это класс Строителя, который имеет методы для добавления каждого ингредиента (
addCheese
,addLettuce
, и т.д.). Каждый метод возвращает самBurgerBuilder
, что позволяет легко выстраивать цепочку вызовов. - Метод
build()
— создает и возвращает объектBurger
с нужными параметрами.
Использование
С помощью цепочки методов addCheese
, addLettuce
, addTomato
мы собираем нужный бургер и вызываем build()
, чтобы получить готовый объект.