0Pricing
Java Academy · Lezione

Pattern Builder con API fluent

Costruisca oggetti complessi passo dopo passo con un builder fluent, evitando costruttori telescopici.

Pattern Builder con API fluent è una lezione Java Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Java Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Java Academy include 4 lezioni in totale.

Il problema dei costruttori telescopici

Quando una classe ha molti parametri opzionali, i costruttori si moltiplicano: 2 parametri, 3 parametri, 4 parametri... Il pattern Builder risolve il problema con un'API fluente di configurazione passo dopo passo.

// Without builder — hard to read:
Pizza p = new Pizza("large", "thin", true, false, true, false, "mozzarella");

Struttura di base di Builder

Crei una classe Builder annidata e statica. La classe esterna ha un costruttore privato che accetta il builder. Ogni setter del builder restituisce this per consentire il concatenamento fluente.

public final class Pizza {
    private final String size, crustType, cheese;
    private final boolean extraSauce, pepperoni;
    private Pizza(Builder b) {
        this.size = b.size; this.crustType = b.crustType;
        this.cheese = b.cheese; this.extraSauce = b.extraSauce;
        this.pepperoni = b.pepperoni;
    }
    public static class Builder {
        private final String size;
        private String crustType = "regular", cheese = "mozzarella";
        private boolean extraSauce, pepperoni;
        public Builder(String size) { this.size = size; }
        public Builder crustType(String c) { this.crustType = c; return this; }
        public Builder cheese(String c)    { this.cheese = c;    return this; }
        public Builder extraSauce()        { this.extraSauce = true; return this; }
        public Builder pepperoni()         { this.pepperoni = true; return this; }
        public Pizza build()               { return new Pizza(this); }
    }
}

Utilizzo di un'API fluente

Il builder si legge come una frase. I parametri obbligatori vengono passati al costruttore; quelli opzionali vengono impostati tramite chiamate di metodo. La chiamata finale a build() produce l'oggetto immutabile.

Pizza p = new Pizza.Builder("large")
    .crustType("thin")
    .extraSauce()
    .pepperoni()
    .build();
System.out.println(p);

Validazione in build()

Aggiunga la logica di validazione all'interno di build() prima di costruire l'oggetto. Generi IllegalStateException o IllegalArgumentException per le combinazioni non valide.

public Pizza build() {
    if (size == null || size.isBlank())
        throw new IllegalArgumentException("Size required");
    if (extraSauce && crustType.equals("stuffed"))
        throw new IllegalStateException("No extra sauce on stuffed crust");
    return new Pizza(this);
}

Builder per oggetti immutabili

Poiché la classe esterna viene creata dal builder in un'unica operazione, tutti i campi possono essere final, rendendo l'oggetto risultante completamente immutabile e thread-safe.

public final class Address {
    private final String street, city, country;
    private final String postalCode;
    private Address(Builder b) { ... } // all finals
    // no setters — immutable!
}

Builder generico con self-type

Per le gerarchie di ereditarietà, utilizzi un parametro di tipo generico ricorsivo (SELF extends Builder<SELF>), così i builder delle sottoclassi restituiscono il tipo della sottoclasse nei metodi concatenati.

public abstract static class Builder<SELF extends Builder<SELF>> {
    String name;
    @SuppressWarnings("unchecked")
    public SELF name(String n) { this.name = n; return (SELF) this; }
    public abstract Vehicle build();
}

Lombok @Builder

@Builder di Lombok genera l'intera infrastruttura del builder al momento della compilazione. Utilizzi @Builder.Default per i valori predefiniti dei campi e @Singular per le collection.

@Builder
public class Report {
    private final String title;
    @Builder.Default private final int pageCount = 1;
    @Singular private final List<String> authors;
}
// Usage:
Report r = Report.builder().title("Q4").author("Alice").author("Bob").build();

Builder nel JDK

Molte classi del JDK utilizzano API in stile builder: StringBuilder, HttpRequest.newBuilder(), ProcessBuilder, Stream.Builder. Impari a riconoscere il pattern.

HttpRequest req = HttpRequest.newBuilder()
    .uri(URI.create("https://api.example.com/users"))
    .header("Accept", "application/json")
    .GET()
    .build();

Builder e Factory

Utilizzi Builder quando un oggetto richiede molti parametri e una configurazione passo dopo passo. Utilizzi Factory quando tutte le varianti sono semplici e la creazione può avvenire con una sola chiamata.

Builder per i dati di test

I builder sono particolarmente utili nei test: crei un builder di base in un helper, quindi sovrascriva solo i campi rilevanti per ogni caso di test, mantenendo i test DRY e leggibili.

User defaultUser() { return new User.Builder("test@example.com").name("Test User").build(); }
User adminUser()   { return new User.Builder("admin@example.com").name("Admin").role(ADMIN).build(); }

Thread safety

Il builder non è thread-safe: non condivida un Builder tra più thread. Il prodotto costruito può essere immutabile e thread-safe se tutti i campi sono final e non vengono condivisi oggetti mutabili.

Verifica rapida

Che cosa rende «fluent» un metodo del builder?

Riepilogo

Builder risolve il problema dei costruttori telescopici. Utilizzi una classe Builder annidata e statica, restituisca this da ogni setter, esegua la validazione in build() e produca un oggetto immutabile. @Builder di Lombok automatizza il codice ripetitivo.

Domande Frequenti

La lezione «Pattern Builder con API fluent» è gratuita?

Sì — il testo completo di «Pattern Builder con API fluent» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Java Academy, passa a CoddyKit PRO. Il corso Java Academy include 4 lezioni in totale.

Cosa imparerò in «Pattern Builder con API fluent»?

Costruisca oggetti complessi passo dopo passo con un builder fluent, evitando costruttori telescopici. Eserciti Java Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Java Academy?

Non è richiesta alcuna esperienza precedente. Java Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.

Quanto tempo richiede la lezione «Pattern Builder con API fluent»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Java Academy?

Sì. Ogni lezione Java Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Singleton: implementazioni thread-safe
  2. Pattern Factory Method
  3. Abstract Factory per famiglie di prodotti
  4. Pattern Builder con API fluent
← Torna a Java Academy