Wzorzec projektowy Dekorator
Jego zadaniem jest rozszerzenie funkcjonalności obiektu poprzez dynamiczne dołączenie dodatkowych zachowań.
- Wzorzec ten pozwala na "dekorowanie" zachowania klasy, czyli zmianę jej funkcjonalności bez potrzeby dziedziczenia.
- Jego działanie można upodobnić do dziedziczenia z tą rożnicą, że dziedziczenie rozszerza zachowanie klasy w trakcie kompilacji a dekoratory rozszerzają klasy w czasie działania programu.
Działanie
Dekorator zmienia operacje dowolnego Komponentu przez użycie dodatkowego kodu w stosunku do wywoływanej przy tym operacji obiektu dekorowanego.
Zalety
- Większa ?elastyczność? programowanych rozwiązań niż w przypadku dziedziczenia - dynamiczny odpowiednik dziedziczenia obiekt można dowolnie "udekorować" podczas wykonania.
- uproszczenia kodowania poprzez możliwość rozwoju szeregu klas o określonych funkjach zamiast umieszczania wszystkich zachowań w jednym obiekcie - rozbicie funkcjonalności.
Wady
- Projekty, w ktorych jest używany, charakteryzują się mnogością małych podobnych do siebie obiektow, ktore rożnią się jedynie tym jak są ze sobą połączone. Poznanie i zrozumienie ich w celu modyfikacji może być przez to mocno utrudnione.
- Nie można także korzystać w takich systemach z identyczności obiektow. Dekorator działa jak przezroczysta otoczka, ale z punktu widzenia identyczności obiekt udekorowany nie jest taki sam jak wejściowy.
Stosowalność
- Kiedy chcemy w sposób jawny i dynamiczny dodac nowe zachowania do obiektu bez wpływu na pozostałe obiekty
- Chcemy dodać nowe zachowania do obiektu, wg. Których istnieje możliwość że będą zmieniane w przyszłości
- Kiedy rozszerzanie funkcjonalności poprzez podklasy przestaje być pratyczne, np. jeżeli do hierarchii klas musimy dodać nowe podklasy zmieniające zachowania każdego liścia z danej hierarchii. W danej sytuacji lepiej jest stworzyć nową podklasę klasy głównej, która będzie modyfikować odpowiednie zachowanie.
Struktura
Implementacja
public interface Komponent { public void action(); } public class KonkretnyKomponent implements Komponent { public void action() { /* ciało metody */ } } public KonkretnyDekorator extends Dekorator { public void action() { super.action(); dodanaMetoda(); } private void dodanaMetoda(){ /* ciało metody */ } } public class Dekorator implements Komponent { Komponent kompJeden = new KonkretnyKomponent(); public void action() { kompJeden.action(); } }