Menu
Coddy logo textTech

Builder-Pattern

Teil des Abschnitts Objektorientierte Programmierung der Java-Journey von Coddy — Lektion 67 von 87.

Das Builder-Pattern ist ein Erzeugungsmuster, das ein häufiges Problem löst: die Konstruktion komplexer Objekte mit vielen optionalen Parametern. Anstatt mehrere Konstruktoren zu erstellen oder null für nicht verwendete Parameter zu übergeben, ermöglicht es der Builder, Objekte Schritt für Schritt zu konstruieren.

Stellen Sie sich vor, Sie erstellen ein User-Objekt mit Pflichtfeldern (name, email) und optionalen Feldern (age, phone, address). Ohne einen Builder würden Sie Teleskop-Konstruktoren oder einen unübersichtlichen Konstruktor mit vielen Parametern benötigen. Das Builder-Pattern bietet einen saubereren Ansatz:

public class User {
    private final String name;    // erforderlich
    private final String email;   // erforderlich
    private final int age;        // optional
    private final String phone;   // optional
    
    private User(UserBuilder builder) {
        this.name = builder.name;
        this.email = builder.email;
        this.age = builder.age;
        this.phone = builder.phone;
    }
    
    public static class UserBuilder {
        private final String name;
        private final String email;
        private int age;
        private String phone;
        
        public UserBuilder(String name, String email) {
            this.name = name;
            this.email = email;
        }
        
        public UserBuilder age(int age) {
            this.age = age;
            return this;
        }
        
        public UserBuilder phone(String phone) {
            this.phone = phone;
            return this;
        }
        
        public User build() {
            return new User(this);
        }
    }
}

Die Methoden des Builders geben this zurück und ermöglichen so Method Chaining – eine flüssige, lesbare Art, Objekte zu konstruieren:

User user = new User.UserBuilder("Alice", "alice@email.com")
    .age(25)
    .phone("555-1234")
    .build();

Beachten Sie, dass der User-Konstruktor privat ist – Objekte können nur über den Builder erstellt werden. Dieses Muster glänzt, wenn Objekte viele optionale Felder haben, was Ihren Code lesbarer und weniger fehleranfällig macht als lange Parameterlisten.

challenge icon

Aufgabe

Einfach

Lassen Sie uns ein Pizza-Bestellsystem mit dem Builder-Pattern erstellen! Anstatt sich mit einem Konstruktor herumzuschlagen, der Dutzende von Parametern für alle möglichen Beläge und Optionen entgegennimmt, erstellen Sie einen flüssigen Builder, der die Pizza-Anpassung sauber und lesbar macht.

Sie werden Ihren Code in zwei Dateien organisieren:

  • Pizza.java: Erstellen Sie eine Pizza-Klasse, die das Builder-Pattern für die Konstruktion verwendet. Ihre Pizza sollte die folgenden Felder haben:

    size (String) - erforderlich, repräsentiert die Pizzagröße

    cheese (boolean) - optional, Standardwert ist false

    pepperoni (boolean) - optional, Standardwert ist false

    mushrooms (boolean) - optional, Standardwert ist false

    Der Pizza-Konstruktor sollte privat sein und nur einen PizzaBuilder als Parameter akzeptieren, wobei alle Werte vom Builder in die Felder der Pizza kopiert werden.

    Fügen Sie eine getDescription()-Methode hinzu, die einen String in diesem Format zurückgibt: [size] Pizza with: [toppings], wobei toppings eine kommagetrennte Liste der Beläge ist, die true sind (Cheese, Pepperoni, Mushrooms). Wenn keine Beläge ausgewählt sind, sollte der Belag-Teil einfach no toppings lauten.

    Erstellen Sie eine statische innere Klasse PizzaBuilder mit:

    • Einem Konstruktor, der den erforderlichen size-Parameter entgegennimmt
    • Methoden cheese(), pepperoni() und mushrooms(), die jeweils den entsprechenden Boolean auf true setzen und this für das Chaining zurückgeben
    • Einer build()-Methode, die eine neue Pizza zurückgibt
  • Main.java: Demonstrieren Sie Ihren Pizza-Builder in Aktion! Sie erhalten vier Eingaben: die Pizzagröße (String) und drei yes/no-Werte (Strings), die angeben, ob Käse, Peperoni bzw. Pilze hinzugefügt werden sollen.

    Erstellen Sie einen PizzaBuilder mit der angegebenen Größe. Verketten Sie dann basierend auf jeder yes/no-Eingabe die entsprechenden Belag-Methoden. Wenn die Eingabe "yes" ist, rufen Sie diese Belag-Methode auf; wenn sie "no" ist, überspringen Sie diese. Rufen Sie schließlich build() auf, um Ihre Pizza zu erstellen.

    Geben Sie das Ergebnis des Aufrufs von getDescription() für Ihre fertige Pizza aus.

Sie erhalten vier Eingaben in der Reihenfolge: size (String), add cheese (String: "yes" oder "no"), add pepperoni (String: "yes" oder "no"), add mushrooms (String: "yes" oder "no").

Zum Beispiel wäre bei den Eingaben Large, yes, no, yes Ihre Ausgabe: Large Pizza with: Cheese, Mushrooms

Beachten Sie, wie das Builder-Pattern es Ihnen ermöglicht, Pizzas mit jeder beliebigen Kombination von Belägen zu konstruieren, ohne separate Konstruktoren für jede Möglichkeit zu benötigen!

Spickzettel

Das Builder-Muster (Erbauer-Muster) ist ein Erzeugungsmuster zur Konstruktion komplexer Objekte mit vielen optionalen Parametern. Es vermeidet "Telescoping Constructors" und lange Parameterlisten, indem Objekte Schritt für Schritt aufgebaut werden.

Struktur

Das Muster besteht aus:

  • Einer Klasse mit einem privaten Konstruktor, der nur einen Builder akzeptiert
  • Einer statischen inneren Builder-Klasse, die das Objekt konstruiert
  • Builder-Methoden, die this für Method Chaining (Methodenverkettung) zurückgeben
  • Einer build()-Methode, die das finale Objekt erstellt

Implementierungsbeispiel

public class User {
    private final String name;    // erforderlich
    private final String email;   // erforderlich
    private final int age;        // optional
    private final String phone;   // optional
    
    private User(UserBuilder builder) {
        this.name = builder.name;
        this.email = builder.email;
        this.age = builder.age;
        this.phone = builder.phone;
    }
    
    public static class UserBuilder {
        private final String name;
        private final String email;
        private int age;
        private String phone;
        
        public UserBuilder(String name, String email) {
            this.name = name;
            this.email = email;
        }
        
        public UserBuilder age(int age) {
            this.age = age;
            return this;
        }
        
        public UserBuilder phone(String phone) {
            this.phone = phone;
            return this;
        }
        
        public User build() {
            return new User(this);
        }
    }
}

Verwendung mit Method Chaining

User user = new User.UserBuilder("Alice", "alice@email.com")
    .age(25)
    .phone("555-1234")
    .build();

Das Builder-Muster ist ideal, wenn Objekte viele optionale Felder haben, da es im Vergleich zu Konstruktoren mit zahlreichen Parametern lesbaren und wartbaren Code bietet.

Probier es selbst

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Eingaben lesen
        String size = scanner.nextLine();
        String addCheese = scanner.nextLine();
        String addPepperoni = scanner.nextLine();
        String addMushrooms = scanner.nextLine();
        
        // TODO: Erstelle einen PizzaBuilder mit der angegebenen Größe
        // TODO: Verkette die Topping-Methoden basierend auf den yes/no Eingaben
        // TODO: Baue die Pizza und gib ihre Beschreibung aus
        
    }
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung