제이온

[Efektywna Java] Element 2. Jeśli konstruktor ma wiele parametrów, rozważ użycie buildera

  • Język oryginalny: Koreański
  • Kraj: Wszystkie krajecountry-flag
  • TO

Utworzono: 2024-04-27

Utworzono: 2024-04-27 00:46

Wzór wzorca budowniczego (Builder)

Zarówno statyczne fabryki, jak i konstruktory mają trudności z odpowiednim radzeniem sobie z dużą liczbą parametrów. Na przykład, jeśli klasa ma 6 pól i chcemy utworzyć konstruktor dla 2 parametrów, 3 parametrów itd., możemy skorzystać z wzorca budowniczego, pokazanego poniżej.



Jednak nawet to może być mylące, gdy liczba parametrów rośnie. Podczas czytania kodu trudno jest zrozumieć znaczenie poszczególnych wartości, a także łatwo pomylić parametry o tym samym typie i wprowadzić nieprawidłowe wartości.


Wzorzec Java Beans

Wzorzec Java Beans tworzy obiekt za pomocą konstruktora bez parametrów, a następnie ustawia żądane wartości parametrów za pomocą metod setter.



Wzorzec Java Beans pozwala na tworzenie obiektów bez obawy o pomyłkę w wartościach parametrów, nawet gdy jest ich dużo. Jednak tworzenie obiektu wymaga wywołania wielu metod setter, co może prowadzić do naruszenia spójności obiektu przed jego pełnym utworzeniem. Z tego powodu nie można tworzyć klas niezmiennych.


Wzorzec budowniczego (Builder)

Wzorzec budowniczego łączy w sobie stabilność wzorca budowniczego i czytelność wzorca Java Beans. Jest to najczęściej stosowany wzorzec w takich sytuacjach.

Zamiast tworzyć obiekt bezpośrednio, klient wywołuje konstruktor z wymaganymi parametrami, aby uzyskać obiekt budowniczego. Następnie, za pomocą metod setter dostarczonych przez obiekt budowniczego, ustawia żądane parametry opcjonalne. Na koniec wywołuje metodę build() bez parametrów, aby uzyskać żądany obiekt.



Konstruktor klasy Builder przyjmuje tylko wymagane parametry, a pozostałe parametry opcjonalne są ustawiane za pomocą metod setter. Na koniec metoda build() tworzy pełny obiekt NutritionFactsWithBuilderPattern. Klasa NutritionFactsWithBuilderPattern jest niezmienna, a metody setter klasy Builder zwracają samą klasę Builder, co pozwala na łączenie wywołań. Ten sposób nazywany jest płynnym interfejsem API lub łączeniem metod.



Z punktu widzenia klienta, wzorzec budowniczego upraszcza pisanie i czytanie kodu.


Wzorzec budowniczego dobrze komponuje się z hierarchicznie zaprojektowanymi klasami


Klasa Pizza.Builder jest generycznym typem z rekurencyjnym ograniczeniem typu, a dodana abstrakcyjna metoda self() pozwala klasom potomnym obsługiwać łączenie metod bez konieczności rzutowania. W klasach potomnych ta abstrakcyjna metoda powinna zwracać samą siebie.

Przyjrzyjmy się teraz klasom potomnym Pizza, czyli pizzy nowojorskiej i calzone, aby zobaczyć elastyczność wzorca budowniczego.



Metoda build() każdej klasy potomnej zwraca konkretną klasę potomną. Funkcja, w której metoda klasy potomnej zwraca typ, który jest podtypem typu zwracanego przez metodę klasy nadrzędnej, nazywana jest kowariantnym typem zwrotnym. Dzięki tej funkcji klient nie musi rzutować typów.



Klient może używać wyliczeń Pizza i jej klas potomnych, a także odpowiednich metod do tworzenia obiektów.


Wady wzorca budowniczego

  • Konieczność utworzenia obiektu budowniczego.
  • Kod może być rozbudowany.


Podsumowanie

Jeśli konstruktor lub statyczna metoda fabryczna musi obsługiwać dużą liczbę parametrów, warto rozważyć użycie wzorca budowniczego.


Źródła

  • Effective Java

Komentarze0