Middle
Cos'è il pattern di progettazione 'Builder'?
sobes.tech AI
Risposta dell'AI
Il pattern di progettazione "Builder" (Costruttore) è un pattern creazionale che fornisce un modo per creare un oggetto complesso passo dopo passo. Separa il processo di costruzione di un oggetto complesso dalla sua rappresentazione, permettendo di usare lo stesso processo di costruzione per creare diverse rappresentazioni.
Componenti chiave del pattern:
- Builder: Interfaccia astratta o concreta (o classe) che definisce un insieme di metodi per costruire passo dopo passo le parti del prodotto.
- ConcreteBuilder: Implementazione concreta di Builder che crea una rappresentazione specifica del prodotto. Conosce tutti i dettagli della costruzione.
- Director: Classe opzionale, ma spesso usata. Definisce l'ordine in cui vengono chiamati i passaggi di costruzione per creare una configurazione specifica del prodotto.
- Product: Oggetto complesso che viene costruito. È composto da molte parti.
Vantaggi:
- Permette di creare oggetti complessi passo dopo passo, evitando costruttori "telescopici" (costruttori con molti parametri).
- Incapsula la logica di creazione dell'oggetto complesso.
- Facilita la modifica della rappresentazione interna del prodotto.
- Permette di usare lo stesso processo di costruzione per creare diverse varianti del prodotto.
Applicabilità:
- Quando il processo di creazione di un oggetto coinvolge molti passaggi e questi devono essere eseguiti in un ordine specifico.
- Quando è necessario avere diverse rappresentazioni dello stesso oggetto.
- Quando il costruttore dell'oggetto ha molti parametri opzionali.
Esempio:
// Prodotto
class Pizza {
private String dough = "";
private String sauce = "";
private List<String> toppings = new ArrayList<>();
public void setDough(String dough) {
this.dough = dough;
}
public void setSauce(String sauce) {
this.sauce = sauce;
}
public void addTopping(String topping) {
this.toppings.add(topping);
}
@Override
public String toString() {
return "Pizza con impasto: " + dough + ", salsa: " + sauce + ", condimenti: " + toppings;
}
}
// Interfaccia del Builder
interface PizzaBuilder {
void buildDough();
void buildSauce();
void buildToppings();
Pizza getPizza();
}
// Builder concreto
class MargheritaPizzaBuilder implements PizzaBuilder {
private Pizza pizza = new Pizza();
@Override
public void buildDough() {
pizza.setDough("crosta sottile");
}
@Override
public void buildSauce() {
pizza.setSauce("pomodoro");
}
@Override
public void buildToppings() {
pizza.addTopping("mozzarella");
pizza.addTopping("basilico");
}
@Override
public Pizza getPizza() {
return this.pizza;
}
}
// Direttore (opzionale)
class Cook {
private PizzaBuilder pizzaBuilder;
public void setPizzaBuilder(PizzaBuilder pb) {
pizzaBuilder = pb;
}
public Pizza getPizza() {
return pizzaBuilder.getPizza();
}
public void constructPizza() {
pizzaBuilder.buildDough();
pizzaBuilder.buildSauce();
pizzaBuilder.buildToppings();
}
}
// Uso
public class BuilderExample {
public static void main(String[] args) {
Cook cook = new Cook();
PizzaBuilder margheritaBuilder = new MargheritaPizzaBuilder();
cook.setPizzaBuilder(margheritaBuilder);
cook.constructPizza();
Pizza margherita = cook.getPizza();
System.out.println(margherita);
}
}
Nel contesto dell'automazione dei test, "Builder" viene spesso utilizzato per creare dati di test o oggetti di test complessi (ad esempio, un oggetto utente con molteplici attributi, un ordine con più posizioni), quando è necessario configurare in modo flessibile diverse varianti di questi dati per diversi scenari di test.