Что такое паттерн проектирования Builder (Строитель)?

«Что такое паттерн проектирования Builder (Строитель)?» — вопрос из категории Паттерны, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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

Проблема: Конструктор объекта с множеством параметров (особенно опциональных) становится громоздким и нечитаемым ("телескопический конструктор").

Решение: Вынести процесс конструирования в отдельный объект-строитель.

Классическая реализация на Swift:

// Продукт, который мы строим
class Pizza {
    let size: Int
    let cheese: Bool
    let pepperoni: Bool
    let mushrooms: Bool

    init(builder: PizzaBuilder) {
        self.size = builder.size
        self.cheese = builder.cheese
        self.pepperoni = builder.pepperoni
        self.mushrooms = builder.mushrooms
    }
}

// Строитель
class PizzaBuilder {
    var size: Int = 12
    var cheese: Bool = false
    var pepperoni: Bool = false
    var mushrooms: Bool = false

    func setSize(_ size: Int) -> PizzaBuilder {
        self.size = size
        return self
    }

    func addCheese() -> PizzaBuilder {
        self.cheese = true
        return self
    }

    func addPepperoni() -> PizzaBuilder {
        self.pepperoni = true
        return self
    }

    func addMushrooms() -> PizzaBuilder {
        self.mushrooms = true
        return self
    }

    func build() -> Pizza {
        return Pizza(builder: self)
    }
}

// Использование (Fluent Interface)
let myPizza = PizzaBuilder()
    .setSize(16)
    .addCheese()
    .addPepperoni()
    .build()

Director (Распорядитель): Часто используется для определения типовых последовательностей шагов построения.

class PizzaDirector {
    func createMargherita(builder: PizzaBuilder) -> Pizza {
        return builder
            .setSize(12)
            .addCheese()
            .build()
    }

    func createPepperoniFeast(builder: PizzaBuilder) -> Pizza {
        return builder
            .setSize(16)
            .addCheese()
            .addPepperoni()
            .build()
    }
}

Преимущества:

  • Пошаговое создание сложных объектов.
  • Изоляция сложного кода сборки.
  • Повторное использование процесса конструирования.
  • Улучшение читаемости кода создания объекта.