BLOG

Wzorzec Dekorator

Dekorator to strukturalny wzorzec projektowy pozwalający dodawać nowe obowiązki obiektom poprzez umieszczanie tych obiektów w specjalnych obiektach opakowujących, które zawierają odpowiednie zachowania.
Dekorator znany jest również pod nazwą “Nakładka” – to słowo dobrze wyraża główną ideę tego wzorca. Nakładka jest obiektem który może być połączony z jakimś docelowym obiektem, zawiera ten sam zestaw metod jak obiekt docelowy i deleguje mu wszelkie otrzymywane żądania.

Załóżmy, że chcemy zaimplementować różne rodzaje samochodów – możemy stworzyć interfejs Car, aby zdefiniować metodę konstruowania samochodu. Następnie możemy tworzyć różne rodzaje samochodów – standardowe, sportowe, luksusowe. Hierarchia będzie jak poniżej:

Ale co jeśli będziemy chcieć samochód, który ma zarówno cechy auta luksusowego jak i sportowego? Lub będziemy mieć znacznie więcej rodzajów aut. Do tego chcielibyśmy wskazać, które z cech mają zostać dodane jako pierwsze.  Implementacja wykorzystująca dziedziczenie i kompozycję będzie trudna do zarządzania. W takiej sytuacji warto zastosować właśnie wzorzec dekorator.

Na początku tworzymy interfejs:

Naszą implementacją konkretnego komponentu będzie klasa BasicCar

Bazowy dekorator implementuje interfejs komponentu:

Konkretni Dekoratorzy definiują dodatkowe zachowania które można przypisać do komponentów dynamicznie. Konkretni dekoratorzy nadpisują metody dekoratora bazowego i wykonują swoje działania albo przed, albo po wywołaniu metody klasy-rodzica. Możemy mieć klasy LuxuryCar i SportsCar.

Program testowy:

Zastosowanie:
gdy chcemy przypisywać dodatkowe obowiązki obiektom w trakcie działania programu, bez psucia kodu, który z tych obiektów korzysta
gdy rozszerzenie zakresu obowiązków obiektu za pomocą dziedziczenia byłoby niepraktyczne lub niemożliwe

Zalety:
– można rozszerzać zachowanie obiektu bez tworzenia podklasy
– można dodawać lub usuwać obowiązku obiektu w trakcie działania programu
– możliwe jest łączenie wielu zachowań poprzez nałożenie wielu dekoratorów na obiekt
– zasada pojedynczej odpowiedzialności – można podzielić klasę monolityczną, która implementuje wiele wariantów zachowań na mniejsze klasy

Wady:
– zabranie jednej konkretnej nakładki ze środka stosu nakładek jest trudne
– trudno jest zaimplementować dekorator w taki sposób, aby jego zachowanie nie zależało od kolejności ułożenia nakładek na stosie
– bazuje na dziedziczeniu, a w javie klasy mogą dziedziczyć tylko po jednym rodzicu to wykorzystanie tego wzorca blokuje dziedziczenie po jakiś klasach potrzebnych z biznesowego punktu widzenia
– pomimo ograniczania ilości klas dekorujących, i tak tworzy się ich spora ilość

guest
0 komentarzy
Inline Feedbacks
View all comments