Dekorator (wzorzec projektowy)
Dekorator – wzorzec projektowy należący do grupy wzorców strukturalnych. Pozwala na dodanie nowej funkcji do istniejących klas dynamicznie podczas działania programu.
Wzorzec dekoratora polega na opakowaniu oryginalnej klasy w nową klasę „dekorującą”. Zwykle przekazuje się oryginalny obiekt jako parametr konstruktora dekoratora, metody dekoratora wywołują metody oryginalnego obiektu i dodatkowo implementują nową funkcję.
Dekoratory są alternatywą dla dziedziczenia. Dziedziczenie rozszerza zachowanie klasy w trakcie kompilacji, w przeciwieństwie do dekoratorów, które rozszerzają klasy w czasie działania programu.
Ponieważ w większości obiektowych języków programowania nie można tworzyć nowych klas podczas działania programu i zwykle nie można przewidzieć z góry wszystkich kombinacji rozszerzeń klas, konieczne by było stworzenie nowej klasy dla każdej kombinacji. Dekoratory są obiektami tworzonymi w czasie działania programu i mogą być łączone w różne kombinacje bezpośrednio przy użyciu.
Przykładowe zastosowanie
Rozważmy okno w graficznym interfejsie użytkownika. By pozwolić na przewijanie jego zawartości, należy dodać do niego poziome lub pionowe paski przewijania. Okna są reprezentowane przez instancję klasy Okno i klasa ta nie powinna posiadać żadnych metod dodających paski przewijania. Można utworzyć podklasę PrzewijaneOkno, która udostępniałaby te metody lub stworzyć OknoDekoratorPrzewijane, który jedynie dodawałby tę funkcję do istniejących obiektów Okno. W tym miejscu działałyby oba rozwiązania.
Teraz załóżmy, że potrzeba dodać ramki dookoła okien. I w tym przypadku klasa Okno nie ma takiej funkcji. Pojawia się problem z podklasą PrzewijaneOkno, bo aby dodać ramki do wszystkich okien, potrzeba stworzyć podklasy OknoZRamką i OknoPrzewijaneZRamką. Problem staje się jeszcze większy z każdą kolejną opcją. W przypadku dekoratorów wystarczy stworzyć jedną klasę OknoDekoratorRamka - podczas działania programu można dynamicznie dekorować istniejące okna z OknoDekoratorPrzewijane lub OknoDekoratorRamka lub oboma.
Przykładem zastosowania wzorca dekoratora jest implementacja strumieni I/O w Javie.
Struktura wzorca
Konsekwencje stosowania
- Zapewnia większą elastyczność niż statyczne dziedziczenie[1].
- Pozwala uniknąć tworzenia przeładowanych funkcjami klas na wysokich poziomach hierarchii[1].
- Dekorator i powiązany z nim komponent nie są identyczne[1].
- Powstawanie wielu małych obiektów[1].
Podobne wzorce
Przykłady
Przypisy
- ↑ a b c d Gamma i in. 2010 ↓, s. 155.
- ↑ Gamma i in. 2010 ↓, s. 160.
Bibliografia
- Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides: Wzorce projektowe. Elementy oprogramowania obiektowego wielokrotnego użytku. Gliwice: Helion, 2010. ISBN 978-83-246-2662-5.