Sobes.tech
Middle

Wat is het ontwerp patroon 'Builder'?

sobes.tech AI

Antwoord van AI

Het "Builder"-patroon is een creational pattern dat bedoeld is om complexe objecten stapsgewijs te maken. Het scheidt het bouwproces van een complex object van de representatie ervan, zodat hetzelfde bouwproces verschillende representaties kan creëren.

Werking principes:

  1. Scheiding: Scheidt de logica van het creëren van het object van het object zelf.
  2. Delegatie: De klantcode (Director) delegeert het maken van het object aan een aparte klasse (Builder).
  3. Stapsgewijze creatie: Het object wordt opgebouwd uit componenten met behulp van een reeks methoden van de builder.

Belangrijkste deelnemers:

  • Product: Het complexe object dat we willen bouwen. Het is onafhankelijk van het bouwproces.
  • Builder: Abstracte interface die de stappen definieert om het Product te bouwen.
  • ConcreteBuilder: Concrete implementatie van Builder, die de bouwstappen uitvoert en een methode biedt om het voltooide Product te verkrijgen.
  • Director (Optioneel): Bepaalt de volgorde van de aanroepen van de bouwstappen. Het is niet verplicht, de klantcode kan direct met ConcreteBuilder werken.

Voordelen:

  • Maakt het mogelijk om objecten met veel optionele parameters op een leesbaardere manier te maken dan met constructoren met veel argumenten of ketens van setters.
  • Maakt het mogelijk om verschillende variaties van hetzelfde object te maken met hetzelfde bouwproces.
  • Verbergt de interne structuur van het te maken object.

Nadelen:

  • Kan het aantal klassen in het project vergroten (Builder, ConcreteBuilder, Product, Director).

Voorbeeld van gebruik: Het maken van een Pizza-object met verschillende ingrediënten.

// 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 met deeg=" + dough + ", saus=" + sauce + ", kaas=" + 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<>()); // Initialiseer de lijst
    }

    @Override
    public void buildDough() {
        pizza.setDough("Dun deeg");
    }

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

    @Override
    public void buildCheese() {
        pizza.setCheese("Mozzarella");
    }

    @Override
    public void addTopping(String topping) {
        // Margherita voegt geen toppings toe behalve de basisingrediënten
    }

    @Override
    public Pizza getPizza() {
        return this.pizza;
    }
}
// Director (Optioneel)
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();
        // Andere methoden kunnen worden aangeroepen, bijvoorbeeld addTopping() in een andere builder
    }
}

Gebruik:

// Klantcode
Kitchen kitchen = new Kitchen();
PizzaBuilder margheritaBuilder = new MargheritaPizzaBuilder();

kitchen.setPizzaBuilder(margheritaBuilder);

kitchen.constructPizza();

Pizza margherita = kitchen.getPizza();
System.out.println(margherita); // Output: Pizza met dun deeg, tomatensaus, mozzarella, toppings=[]