Sobes.tech
Middle

Šta je obrazac dizajna 'Builder'?

sobes.tech АИ

Одговор од АИ

Моделот "Builder" (Градител) е шаблон за създаване, предназначен за стъпково изграждане на сложни обекти. Той отделя процеса на конструиране на сложен обект от неговото представяне, така че същият процес на изграждане може да създава различни представяния.

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

  1. Разделяне: Отделя логиката за създаване на обекта от самия обект.
  2. Делегиране: Клиентският код (Директор) делегира създаването на обекта на отделен клас (Builder).
  3. Стъпково създаване: Обектът се сглобява от съставни части с помощта на набор от методи на строителя.

Основни участници:

  • Product: Сложен обект, който искаме да построим. Не зависи от процеса на създаване.
  • Builder: Абстрактен интерфейс, който определя стъпките за изграждане на Product.
  • ConcreteBuilder: Конкретна реализация на Builder, която реализира стъпките на изграждане и предоставя метод за получаване на готовия Product.
  • Директор (По избор): Определя реда на извикване на стъпките на изграждане. Не е задължително, клиентският код може да взаимодейства директно с ConcreteBuilder.

Предимства:

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

Недостатъци:

  • Може да увеличи броя на класовете в проекта (Builder, ConcreteBuilder, Product, Директор).

Пример за използване: Създаване на обект от клас 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) {
        // Маргарита не добавя toppings, освен основните
    }

    @Override
    public Pizza getPizza() {
        return this.pizza;
    }
}
// Директор (По избор)
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() в друг builder
    }
}

Използване:

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

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

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