Menu
Coddy logo textTech

Builder-Muster

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

Das Builder Pattern ist ein erzeugendes Entwurfsmuster, das ein häufiges Problem löst: die Erstellung komplexer Objekte mit vielen optionalen Parametern. Anstatt mehrere Konstruktoren zu erstellen oder für nicht verwendete Parameter null zu übergeben, kannst du mit dem Builder Objekte Schritt für Schritt erstellen.

Stell dir vor, du erstellst ein User-Objekt mit erforderlichen Feldern (Name, E-Mail) und optionalen Feldern (Alter, Telefon, Adresse). Ohne einen Builder bräuchtest du verschachtelte Konstruktoren oder einen unübersichtlichen Konstruktor mit vielen Parametern. Das Builder-Muster bietet einen übersichtlicheren 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 Methodenverkettung: eine flüssige, gut lesbare Möglichkeit, Objekte zu erstellen:

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

Beachte, dass der Konstruktor von User privat ist: Objekte können nur über den Builder erstellt werden. Dieses Muster kommt besonders zur Geltung, wenn Objekte viele optionale Felder haben, und macht deinen Code lesbarer und weniger fehleranfällig als lange Parameterlisten.

challenge icon

Aufgabe

Einfach

Erstellen wir ein Pizza-Bestellsystem mit dem Builder Pattern! Statt mit einem Konstruktor zu arbeiten, der Dutzende von Parametern für alle möglichen Beläge und Optionen entgegennimmt, erstellst du einen Fluent Builder, der die Anpassung der Pizza übersichtlich und lesbar macht.

Du organisierst deinen Code über zwei Dateien:

  • Pizza.java: Erstelle eine Pizza-Klasse, die für ihre Erstellung das Builder Pattern verwendet. Deine Pizza sollte die folgenden Felder haben:

    size (String) – erforderlich, stellt die Pizzagröße dar

    cheese (boolean) – optional, standardmäßig false

    pepperoni (boolean) – optional, standardmäßig false

    mushrooms (boolean) – optional, standardmäßig false

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

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

    Erstelle eine statische innere Klasse PizzaBuilder mit:

    • Einem Konstruktor, der den erforderlichen Parameter size entgegennimmt
    • Methoden cheese(), pepperoni() und mushrooms(), die jeweils den entsprechenden Boolean-Wert auf true setzen und für Verkettungen this zurückgeben
    • Einer build()-Methode, die eine neue Pizza zurückgibt
  • Main.java: Zeige deinen Pizza Builder in Aktion! Du erhältst vier Eingaben: die Pizzagröße (String) und drei Ja/Nein-Werte (Strings), die angeben, ob Cheese, Pepperoni beziehungsweise Mushrooms hinzugefügt werden sollen.

    Erstelle mit der angegebenen Größe einen PizzaBuilder. Verkette anschließend abhängig von jeder Ja/Nein-Eingabe die entsprechenden Belagmethoden. Wenn die Eingabe "yes" lautet, rufe die jeweilige Belagmethode auf; bei "no" überspringe sie. Rufe schließlich build() auf, um deine Pizza zu erstellen.

    Gib das Ergebnis des Aufrufs von getDescription() für deine fertige Pizza aus.

Du erhältst vier Eingaben in dieser Reihenfolge: size (String), add cheese (String: "yes" oder "no"), add pepperoni (String: "yes" oder "no"), add mushrooms (String: "yes" oder "no").

Bei den Eingaben Large, yes, no, yes würde deine Ausgabe beispielsweise lauten: Large Pizza with: Cheese, Mushrooms

Beachte, wie das Builder Pattern es dir ermöglicht, Pizzen mit beliebigen Kombinationen von Belägen zu erstellen, ohne für jede Möglichkeit separate Konstruktoren zu benötigen!

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 gegebenen Größe
        // TODO: Verkette Topping-Methoden basierend auf Ja/Nein-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

Übe selbstständig: Online-Java-Compiler