Menu
Coddy logo textTech

Wzorzec Builder

Część sekcji Programowanie obiektowe ścieżki Java w Coddy. Lekcja 67 z 87.

Wzorzec Builder to kreacyjny wzorzec projektowy, który rozwiązuje częsty problem: tworzenie złożonych obiektów z wieloma opcjonalnymi parametrami. Zamiast tworzyć wiele konstruktorów lub przekazywać null dla nieużywanych parametrów, możesz za pomocą Buildera konstruować obiekty krok po kroku.

Rozważ utworzenie obiektu User z wymaganymi polami (imię, e-mail) i opcjonalnymi (wiek, telefon, adres). Bez wzorca Buildera potrzebne byłyby konstruktory teleskopowe lub nieporządny konstruktor z wieloma parametrami. Wzorzec Builder oferuje czystsze podejście:

public class User {
    private final String name;    // wymagane
    private final String email;   // wymagane
    private final int age;        // opcjonalne
    private final String phone;   // opcjonalne
    
    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);
        }
    }
}

Metody Buildera zwracają this, umożliwiając łączenie metod: płynny i czytelny sposób konstruowania obiektów:

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

Zwróć uwagę, że konstruktor User jest prywatny: obiekty można tworzyć tylko za pomocą Buildera. Ten wzorzec sprawdza się doskonale, gdy obiekty mają wiele opcjonalnych pól, dzięki czemu kod jest bardziej czytelny i mniej podatny na błędy niż w przypadku długich list parametrów.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system zamawiania pizzy z użyciem wzorca Builder! Zamiast korzystać z konstruktora przyjmującego dziesiątki parametrów dla wszystkich możliwych dodatków i opcji, utworzysz płynny builder, dzięki któremu dostosowywanie pizzy będzie przejrzyste i czytelne.

Rozmieścisz swój kod w dwóch plikach:

  • Pizza.java: Utwórz klasę Pizza, która wykorzystuje wzorzec Builder do tworzenia obiektów. Twoja pizza powinna mieć następujące pola:

    size (String) — wymagane, określa rozmiar pizzy

    cheese (boolean) — opcjonalne, domyślnie ma wartość false

    pepperoni (boolean) — opcjonalne, domyślnie ma wartość false

    mushrooms (boolean) — opcjonalne, domyślnie ma wartość false

    Konstruktor Pizza powinien być prywatny i przyjmować jako parametr wyłącznie PizzaBuilder, kopiując wszystkie wartości z buildera do pól pizzy.

    Dodaj metodę getDescription(), która zwraca ciąg znaków w tym formacie: [size] Pizza with: [toppings], gdzie toppings to oddzielona przecinkami lista dodatków, których wartość wynosi true (Cheese, Pepperoni, Mushrooms). Jeśli nie wybrano żadnych dodatków, część toppings powinna zawierać tylko no toppings.

    Utwórz statyczną klasę wewnętrzną PizzaBuilder, zawierającą:

    • Konstruktor przyjmujący wymagany parametr size
    • Metody cheese(), pepperoni() i mushrooms(), z których każda ustawia odpowiednią wartość logiczną na true i zwraca this, aby umożliwić łańcuchowe wywołania
    • Metodę build(), która zwraca nowy obiekt Pizza
  • Main.java: Pokaż działanie buildera pizzy! Otrzymasz cztery dane wejściowe: rozmiar pizzy (String) oraz trzy wartości tak/nie (String) określające, czy dodać odpowiednio ser, pepperoni i pieczarki.

    Utwórz PizzaBuilder z podanym rozmiarem. Następnie na podstawie każdej wartości tak/nie wywołaj odpowiednią metodę dodatku w łańcuchu. Jeśli wartość wejściowa to "yes", wywołaj metodę danego dodatku; jeśli "no", pomiń ją. Na koniec wywołaj build(), aby utworzyć pizzę.

    Wyświetl wynik wywołania getDescription() na gotowej pizzy.

Otrzymasz cztery dane wejściowe w następującej kolejności: size (String), add cheese (String: "yes" lub "no"), add pepperoni (String: "yes" lub "no"), add mushrooms (String: "yes" lub "no").

Na przykład dla danych wejściowych Large, yes, no, yes wynikiem będzie: Large Pizza with: Cheese, Mushrooms

Zwróć uwagę, że wzorzec Builder pozwala tworzyć pizze z dowolną kombinacją dodatków bez konieczności tworzenia osobnych konstruktorów dla każdej możliwości!

Spróbuj swoich sił

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Odczytaj dane wejściowe
        String size = scanner.nextLine();
        String addCheese = scanner.nextLine();
        String addPepperoni = scanner.nextLine();
        String addMushrooms = scanner.nextLine();
        
        // TODO: Utwórz PizzaBuilder z podanym rozmiarem
        // TODO: Połącz wywołania metod dodających składniki w łańcuch na podstawie odpowiedzi tak/nie
        // TODO: Zbuduj pizzę i wypisz jej opis
        
    }
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Java online