Назад к вопросам
Middle
71
questionbank

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

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

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

Принципы работы:

  1. Разделение: Отделяет логику создания объекта от самого объекта.
  2. Делегирование: Клиентский код (Director) делегирует создание объекта отдельному классу (Builder).
  3. Пошаговое создание: Объект собирается из составных частей с помощью набора методов строителя.

Основные участники:

  • Product: Сложный объект, который мы хотим построить. Не зависит от процесса создания.
  • Builder: Абстрактный интерфейс, определяющий шаги для построения Product.
  • ConcreteBuilder: Конкретная реализация Builder, реализующая шаги построения и предоставляющая метод для получения готового Product.
  • Director (Optional): Определяет порядок вызова шагов построения. Необязателен, клиентский код может напрямую взаимодействовать с ConcreteBuilder.

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

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

Недостатки:

  • Может увеличить количество классов в проекте (Builder, ConcreteBuilder, Product, Director).

Пример использования: Создание объекта класса Pizza с различными ингредиентами.

// Product
public class Pizza {
    private String dough;
    private String sauce;
    private String cheese;
    private List<String> toppings;

    public void setDough(String dough) { this.dough = dough; }
    public void setSauce(String sauce) { this.sauce = sauce; }
    public void setCheese(String cheese) { this.cheese = cheese; }
    public void setToppings(List<String> toppings) { this.toppings = toppings; }

    @Override
    public String toString() {
        return "Pizza with dough=" + dough + ", sauce=" + sauce + ", cheese=" + cheese + ", toppings=" + toppings;
    }
}
// Builder
public interface PizzaBuilder {
    void buildDough();
    void buildSauce();
    void buildCheese();
    void addTopping(String topping);
    Pizza getPizza();
}
// ConcreteBuilder
public class MargheritaPizzaBuilder implements PizzaBuilder {
    private Pizza pizza;

    public MargheritaPizzaBuilder() {
        this.pizza = new Pizza();
        this.pizza.setToppings(new ArrayList<>()); // Инициализация списка
    }

    @Override
    public void buildDough() {
        pizza.setDough("Thin crust");
    }

    @Override
    public void buildSauce() {
        pizza.setSauce("Tomato sauce");
    }

    @Override
    public void buildCheese() {
        pizza.setCheese("Mozzarella");
    }

    @Override
    public void addTopping(String topping) {
        // Маргерита не добавляет топпинги, кроме базовых
    }

    @Override
    public Pizza getPizza() {
        return this.pizza;
    }
}
// Director (Optional)
public class Kitchen {
    private PizzaBuilder pizzaBuilder;

    public void setPizzaBuilder(PizzaBuilder pb) {
        pizzaBuilder = pb;
    }

    public Pizza getPizza() {
        return pizzaBuilder.getPizza();
    }

    public void constructPizza() {
        pizzaBuilder.buildDough();
        pizzaBuilder.buildSauce();
        pizzaBuilder.buildCheese();
        // Могут быть вызваны другие методы, например addTopping() в другом билдере
    }
}

Использование:

// Клиентский код
Kitchen kitchen = new Kitchen();
PizzaBuilder margheritaBuilder = new MargheritaPizzaBuilder();

kitchen.setPizzaBuilder(margheritaBuilder);
kitchen.constructPizza();

Pizza margherita = kitchen.getPizza();
System.out.println(margherita); // Вывод: Pizza with dough=Thin crust, sauce=Tomato sauce, cheese=Mozzarella, toppings=[]