Sobes.tech
Middle

Ce este pattern-ul de proiectare 'Builder'?

sobes.tech AI

Răspuns de la AI

Modelul de proiectare "Builder" (Constructor) este un model creational care oferă o metodă de a crea un obiect complex pas cu pas. El separă procesul de construcție a unui obiect complex de reprezentarea sa, permițând utilizarea aceluiași proces de construcție pentru a crea diferite reprezentări.

Componentele cheie ale modelului:

  • Builder: Interfață abstractă sau concretă (sau clasă), care definește un set de metode pentru construirea pas cu pas a părților produsului.
  • ConcreteBuilder: Implementare concretă a Builder, care creează o reprezentare specifică a produsului. Știe toate detaliile construcției.
  • Director: Clasă opțională, dar frecvent utilizată. Definește ordinea apelurilor pentru pașii construcției pentru a crea o configurație specifică a produsului.
  • Product: Obiect complex care este construit. Este format din mai multe părți.

Avantaje:

  • Permite crearea de obiecte complexe pas cu pas, evitând constructorii "telescopici" (cu mulți parametri).
  • Încarcă logica de creare a unui obiect complex.
  • Facilitează modificarea reprezentării interne a produsului.
  • Permite utilizarea aceluiași proces de construcție pentru a crea diferite variante ale produsului.

Aplicații:

  • Când procesul de creare a unui obiect implică mulți pași și acești pași trebuie să fie executați într-o anumită ordine.
  • Când este necesar să aveți diferite reprezentări ale aceluiași obiect.
  • Când constructorul obiectului are foarte mulți parametri opționali.

Exemplu:

// Produs
class Pizza {
    private String aluat = "";
    private String sos = "";
    private List<String> toppinguri = new ArrayList<>();

    public void setAluat(String aluat) {
        this.aluat = aluat;
    }

    public void setSos(String sos) {
        this.sos = sos;
    }

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

    @Override
    public String toString() {
        return "Pizza cu aluat: " + aluat + ", sos: " + sos + ", toppinguri: " + toppinguri;
    }
}

// Interfața Builder
interface PizzaBuilder {
    void buildAluat();
    void buildSos();
    void buildToppinguri();
    Pizza getPizza();
}

// Builder concret
class MargheritaPizzaBuilder implements PizzaBuilder {
    private Pizza pizza = new Pizza();

    @Override
    public void buildAluat() {
        pizza.setAluat("crust subțire");
    }

    @Override
    public void buildSos() {
        pizza.setSos("roșii");
    }

    @Override
    public void buildToppinguri() {
        pizza.addTopping("mozzarella");
        pizza.addTopping("busuioc");
    }

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

// Director (opțional)
class Bucatar {
    private PizzaBuilder pizzaBuilder;

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

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

    public void construiestePizza() {
        pizzaBuilder.buildAluat();
        pizzaBuilder.buildSos();
        pizzaBuilder.buildToppinguri();
    }
}

// Utilizare
public class BuilderExample {
    public static void main(String[] args) {
        Bucatar bucatar = new Bucatar();
        PizzaBuilder builderMargherita = new MargheritaPizzaBuilder();

        bucatar.setPizzaBuilder(builderMargherita);
        bucatar.construiestePizza();

        Pizza pizzaMargherita = bucatar.getPizza();
        System.out.println(pizzaMargherita);
    }
}

În contextul automatizării testării, "Builder" este adesea utilizat pentru crearea datelor de test sau a obiectelor complexe de testare (de exemplu, un obiect utilizator cu multiple atribute, un obiect comandă cu mai multe poziții), atunci când este necesară configurarea flexibilă a diferitelor variante ale acestor date pentru diferite scenarii de testare.