Sobes.tech
Middle

Co je to návrhový vzor 'Builder'?

sobes.tech AI

Odpověď od AI

Designový vzor "Builder" (Stavitel) je tvůrčí vzor, který poskytuje způsob, jak krok za krokem vytvořit složitý objekt. Odděluje proces konstrukce složitého objektu od jeho reprezentace, což umožňuje použít stejný konstrukční proces k vytvoření různých reprezentací.

Klíčové komponenty vzoru:

  • Builder: Abstrétní nebo konkrétní rozhraní (nebo třída), která definuje sadu metod pro krokové sestavení částí produktu.
  • ConcreteBuilder: Konkrétní implementace Builderu, která vytváří specifickou reprezentaci produktu. Zná všechny detaily konstrukce.
  • Director: Volitelná, ale často používaná třída. Určuje pořadí volání kroků konstrukce, aby vytvořila určitou konfiguraci produktu.
  • Product: Složitý objekt, který je sestavován. Skládá se z mnoha částí.

Výhody:

  • Umožňuje krok za krokem vytvářet složité objekty, vyhýbá se "teleskopickým" konstruktorům (konstruktorům s velkým počtem parametrů).
  • Zapouzdřuje logiku tvorby složitého objektu.
  • Usnadňuje změnu vnitřního zobrazení produktu.
  • Umožňuje použít stejný konstrukční proces k vytvoření různých variant produktu.

Použití:

  • Když proces tvorby objektu zahrnuje mnoho kroků a tyto kroky musí být provedeny v určitém pořadí.
  • Když je třeba mít různé zobrazení téhož objektu.
  • Když má konstruktor objektu velmi mnoho volitelných parametrů.

Příklad:

// Produkt
class Pizza {
    private String těsto = "";
    private String omáčka = "";
    private List<String> přísady = new ArrayList<>();

    public void setTěsto(String těsto) {
        this.těsto = těsto;
    }

    public void setOmáčka(String omáčka) {
        this.omáčka = omáčka;
    }

    public void addPřísada(String přísada) {
        this.přísady.add(přísada);
    }

    @Override
    public String toString() {
        return "Pizza s těstem: " + těsto + ", omáčkou: " + omáčka + ", přísadami: " + přísady;
    }
}

// Rozhraní Builder
interface PizzaBuilder {
    void buildTěsto();
    void buildOmáčka();
    void buildPřísady();
    Pizza getPizza();
}

// Konkrétní Builder
class MargheritaPizzaBuilder implements PizzaBuilder {
    private Pizza pizza = new Pizza();

    @Override
    public void buildTěsto() {
        pizza.setTěsto("tenké těsto");
    }

    @Override
    public void buildOmáčka() {
        pizza.setOmáčka("rajčatová");
    }

    @Override
    public void buildPřísady() {
        pizza.addPřísada("mozzarella");
        pizza.addPřísada("bazalka");
    }

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

// Ředitel (volitelný)
class Kuchař {
    private PizzaBuilder pizzaBuilder;

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

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

    public void sestavitPizza() {
        pizzaBuilder.buildTěsto();
        pizzaBuilder.buildOmáčka();
        pizzaBuilder.buildPřísady();
    }
}

// Použití
public class BuilderExample {
    public static void main(String[] args) {
        Kuchař kuchař = new Kuchař();
        PizzaBuilder margheritaBuilder = new MargheritaPizzaBuilder();

        kuchař.setPizzaBuilder(margheritaBuilder);
        kuchař.sestavitPizza();

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

V kontextu automatizace testování je "Builder" často používán pro tvorbu testovacích dat nebo složitých testovacích objektů (například uživatelský objekt s mnoha atributy, objednávka s několika položkami), kdy je potřeba flexibilně konfigurovat různé varianty těchto dat pro různé testovací scénáře.