Sobes.tech
Middle

Какво е патърнът за дизайн 'Builder'?

sobes.tech AI

Отговор от AI

Моделът "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) {
        // Маргарита не добавя топинги, освен основните
    }

    @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=[]