Builder-mönstret med fluent-API
Konstruera komplexa objekt stegvis med en fluent builder för att undvika telescoping-konstruktorer.
Builder-mönstret med fluent-API är en gratis lektion i Java Academy på CoddyKit. Detta är lektion 4 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Java Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Java Academy innehåller totalt 4 lektioner.
Problemet med teleskoperande konstruktorer
När en klass har många valfria parametrar blir konstruktorerna allt fler: två parametrar, tre parametrar, fyra parametrar och så vidare. Builder-mönstret löser detta med ett fluent-API för stegvis konfigurering.
// Without builder — hard to read:
Pizza p = new Pizza("large", "thin", true, false, true, false, "mozzarella");Grundläggande Builder-struktur
Skapa en statisk nästlad Builder-klass. Den yttre klassen har en privat konstruktor som tar emot buildern. Varje setter i buildern returnerar this för att möjliggöra fluent-kedjor.
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); }
}
}Använda ett fluent-API
Buildern kan läsas som en mening. Obligatoriska parametrar anges i konstruktorn, medan valfria parametrar anges genom metodanrop. Det avslutande anropet till build() skapar det oföränderliga objektet.
Pizza p = new Pizza.Builder("large")
.crustType("thin")
.extraSauce()
.pepperoni()
.build();
System.out.println(p);Validering i build()
Lägg till valideringslogik i build() innan objektet skapas. Kasta IllegalStateException eller IllegalArgumentException för ogiltiga kombinationer.
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 för oföränderliga objekt
Eftersom den yttre klassen skapas från buildern i ett enda steg kan alla fält vara final. Det gör det resulterande objektet helt oföränderligt och trådsäkert.
public final class Address {
private final String street, city, country;
private final String postalCode;
private Address(Builder b) { ... } // all finals
// no setters — immutable!
}Generisk Builder med självrefererande typ
För arvshierarkier använder du en rekursiv generisk typparameter (SELF extends Builder<SELF>) så att builders i underklasser returnerar underklassens typ från kedjade metoder.
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
Lomboks @Builder genererar hela builder-infrastrukturen vid kompilering. Använd @Builder.Default för standardvärden för fält och @Singular för samlingar.
@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 i JDK
Många JDK-klasser använder Builder-liknande API:er: StringBuilder, HttpRequest.newBuilder(), ProcessBuilder och Stream.Builder. Lär dig att känna igen mönstret.
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.example.com/users"))
.header("Accept", "application/json")
.GET()
.build();Builder jämfört med Factory
Använd Builder när ett objekt kräver många parametrar och stegvis konfigurering. Använd Factory när alla varianter är enkla och skapandet kan göras i ett enda anrop.
Builder för testdata
Builders är särskilt användbara i tester: skapa en grundläggande builder i en hjälpfunktion och skriv sedan över endast de fält som är relevanta för varje testfall. Då förblir testerna DRY och lättlästa.
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(); }Trådsäkerhet
Buildern är inte trådsäker i sig — dela inte en Builder mellan trådar. Produkten som byggs kan vara oföränderlig och trådsäker om alla fält är final och inga föränderliga objekt delas.
Snabb kontroll
Vad gör en builder-metod "fluent"?
Sammanfattning
Builder löser problemet med teleskoperande konstruktorer. Använd en statisk nästlad Builder-klass, returnera this från varje setter, validera i build() och skapa ett oföränderligt objekt. Lomboks @Builder automatiserar standardkoden.
Lär dig Java med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 104
- Lektioner
- 374
Vanliga frågor
Är lektionen ”Builder-mönstret med fluent-API” gratis?
Ja – hela texten till ”Builder-mönstret med fluent-API” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Java Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i Java Academy innehåller totalt 4 lektioner.
Vad lär jag mig i ”Builder-mönstret med fluent-API”?
Konstruera komplexa objekt stegvis med en fluent builder för att undvika telescoping-konstruktorer. Ni övar på Java Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig Java Academy?
Du behöver inga förkunskaper. Utbildningen i Java Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 4 av 4.
Hur lång tid tar lektionen ”Builder-mönstret med fluent-API”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här Java Academy-lektionen?
Ja. Varje Java Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Singleton: trådsäkra implementationer
- Fabrikmetodmönstret
- Abstrakt fabrik för produktfamiljer
- Builder-mönstret med fluent-API