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

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

Sobes Copilot

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

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

sobes.tech AI

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

Ключевые компоненты паттерна:

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

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

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

Применимость:

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

Пример:

// Продукт
class Pizza {
    private String dough = "";
    private String sauce = "";
    private List<String> toppings = new ArrayList<>();

    public void setDough(String dough) {
        this.dough = dough;
    }

    public void setSauce(String sauce) {
        this.sauce = sauce;
    }

    public void addTopping(String topping) {
        this.toppings.add(topping);
    }

    @Override
    public String toString() {
        return "Pizza with dough: " + dough + ", sauce: " + sauce + ", toppings: " + toppings;
    }
}

// Интерфейс Строителя
interface PizzaBuilder {
    void buildDough();
    void buildSauce();
    void buildToppings();
    Pizza getPizza();
}

// Конкретный Строитель
class MargheritaPizzaBuilder implements PizzaBuilder {
    private Pizza pizza = new Pizza();

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

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

    @Override
    public void buildToppings() {
        pizza.addTopping("mozzarella");
        pizza.addTopping("basil");
    }

    @Override
    public Pizza getPizza() {
        return this.pizza;
    }
}

// Директор (опционально)
class Cook {
    private PizzaBuilder pizzaBuilder;

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

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

    public void constructPizza() {
        pizzaBuilder.buildDough();
        pizzaBuilder.buildSauce();
        pizzaBuilder.buildToppings();
    }
}

// Использование
public class BuilderExample {
    public static void main(String[] args) {
        Cook cook = new Cook();
        PizzaBuilder margheritaBuilder = new MargheritaPizzaBuilder();

        cook.setPizzaBuilder(margheritaBuilder);
        cook.constructPizza();

        Pizza margherita = cook.getPizza();
        System.out.println(margherita);
    }
}

В контексте автоматизации тестирования, "Строитель" часто используется для создания тестовых данных или сложных тестовых объектов (например, объекта пользователя с множеством атрибутов, объекта заказа с несколькими позициями), когда требуется гибко настраивать различные варианты этих данных для разных тестовых сценариев.