WZORCE PROJEKTOWE STRUKTURALNE Omówimy (W6-W8): Decorator Composite Adapter Bridge Facade Proxy
WYKŁAD 6 Wzorce projektowe strukturalne Decorator Composite
Structural Design Pattern: Decorator Dynamicznie dołcza do obiektów dodatkowe zobowizania. Zapewnia elastyczn alternatyw dla tworzenia podklas w celu rozszerzania funkcjonalnoci. Inne nazwy: Opakowanie (Wrapper)
Uzasadnienie stosowania: Czasami chcemy dołczy pewne zobowizania do niektórych obiektów a nie całych klas. Np. dodanie ramek i pasków przewijania do składników GUI. Dziedziczenie jest kłopotliwe statyczny wybór ramki, na dodatek dla kadego elementu.
Lepszym rozwizaniem jest umieszczenie obiektu dekorowanego (element GUI) wewntrz obiektu dekorujacego (ramka, scrollbars). Dekorator dostosowuje si do interfejsu dekorowanego obiektu stajc si przeroczystym dla klienta obiektu dekorowanego.
Dekorator przekazuje dania do obiektu dekorowanego i moe wykonywa dodatkowe operacje przed lub po otrzymaniu dania. Przeroczysto ta umoliwia rekurencyjne zagniedanie dekoratorów.
Mamy obiekt klasy WidokTekstowy wywietlajcy tekst w okienku. Standardowo nie ma on suwaków. Moemy je doda za pomoc DekoratorZSuwakami. Ramk moemy doda za pomoc DekoratoraZRamkami. Klasy DekoratorZSuwakami i DekoratoraZRamkami s podklasami abstrakcyjnej klasy Dekorator reprezentujcej komponenty wizulane, które ozdabiaj inne komponenty wizualne.
KomponentWizualny +komponent Rysuj() WidokTekstowy Dek orator Rysuj() Rysuj() komponent->ry suj(); DekoratorZSuwakami pozycjasuwaka Rysuj() PrzewinDo() DekoratorZRamkami szerokoscramki Rysuj() RysujRamke() Dekorator::Rysuj(); RysujRamke();
Klasa Dekorator przesyła dania do swojego komponentu a podklasy mog rozszerza to działanie. Jeli klient wie jaki dekorator został wykorzystany, to moe skorzysta z tych rozszerze.
Stosowalno: dynamiczne i przeroczyste dodawanie zobowizania do pojedynczych obiektów dodanie zobowiza, które mog zosta cofnite niepraktyczne rozszerzanie przez podklasy mnóstwo niezalenych rozszerze moe spowodowa eksplozj hierarchii. Struktura:
Komponent +komponent Operacja() KomponentK onkretny Dek orator Operacja() Operacja() k omponent->operacja(); DekoratorKonkretnyA dodanystan Operacja() DekoratorKonkretnyB Operacja() DodaneZachowanie() Dekorator::Operacja(); DodaneZachowanie();
Uczestnicy: Komponent (KomponentWizualny) definiuje interfejs obiektów, do których mona dynamicznie dołcza zobowizania KomponentKonkretny (WidokTekstowy) definiuje obiekt, do którego mona dołcza dodatkowe zobowizania
Dekorator zarzdza odwołaniem do obiektu Komponent i definiuje interfejs dopasowany do interfejsu Komponentu DekoratorKonkretny (.,.) dodaje zobowizania do Komponentu Współpraca: Dekorator przesyła dania do swojego obiektu Komponent. Moe opcjonalnie wykonywa inne operacje przed lub po przesłaniu dania
Konsekwencje: wiksza elastyczno ni przy stosowaniu statycznego dziedziczenia runtime, mieszanie zobowiza, wielokrotne dołczanie właciwoci (podwójna ramka) unikanie przeładowanych właciwociami klas na szczycie hierarchii koncepcja prostej klasy na szczycie wzbogacanej w miar potrzeb przez dekoratory
Dekorator i jego komponent nie s identyczne wiele małych obiektów takie systemy składaj si z wielu małych połczonych ze sob w skomplikowany sposób obiektów ich autorzy mog je bardzo łatwo zmienia, ale trudno je zrozumie i trudno usuwa z nich błdy
Implementacja: zgodno interfejsów obiektu dekorujacego i dekorowanego pomijanie klasy abstrakcyjnej Dekorator gdy dodajemy tylko jedno zobowizanie (po co ujednolica interfejsy) utrzymanie lekkoci klasy Komponent nie powinna definiowa danych zmiana skóry obiektu (Decorator) a zmiana wntrza obiektu (Strategy)
Przykłady: Znane zastosowania: GUI strumienie IO [rys.] Pokrewne wzorce: Adapter zmienia interfejs a nie tylko zobowizania.
Pokrewne wzorce: Adapter zmienia interfejs a nie tylko zobowizania. Kompozyt. Decorator to zdegenerowany Kompozyt z jednym komponentem. Strategia zmienia wntrze obiektu, a Dekorator zewntrze konkurencyjny sposób zmieniania obiektu (Strategia - gdy klasa Komponent jest cika)
Structural Design Pattern: Composite Składa obiekty w struktury drzewiaste reprezentujce hierarchie typu cz-cało. Umoliwia klientom jednakowe traktowanie pojedynczych obiektów i złoe obiektów.
Uzasadnienie stosowania: Aplikacje graficzne umoliwij budowanie złoonych diagramów z mniejszych elementów. Uytkownik moe grupowa mniejsze elementy w wiksze, a te w jeszcze wiksze. Problemem jest fakt, e kod w odrónieniu od uytkownika musi inaczej traktowa elementy pierwotne i kontenery.
Wzorzec pokazuje jak zastosowa składanie rekurencyjne tak aby klienci nie musieli rozrónia elementów pierwotnych od kontenerów.
Obiek tgraficzny Klient Rysuj() Dodaj( : Obiek tgraficzny) Usun( : Obiek tgraficzny) PodajDzieck o( : int) +obiekty graficzne Linia Prost okat Tekst Rysunek Rysuj() Rysuj() Rysuj() Operacja() Dodaj( : ObiektGraficzny) Usun( : ObiektGraficzny) PodajDziecko( : int)
Kluczowa jest tu klasa abstrakcyjna, która reprezentuje zarówno zarówno elementy pierwotne jak i ich konetenery. W przykładzie jest to klasa ObiektGraficzny. Deklaruje ona operacje Rysuj() specyficzne dla obiektów graficznych. Deklaruje te operacje wspólne dla kontenerów pozwalajce na manipulowanie dziemi.
Stosowalno: potrzebna reprezentacja hierarchii czcało wymaganie aby klienci mogli ignorowa rónic midzy złoeniami obiektów a pojedynczymi obiektami
Klient Komponent Operacja() Dodaj( : Komponent) Usun( : Komponent) PodajDzieck o( : int) +dzieci Kompozyt Lisc Operacja() Operacja() Dodaj() Usun() PodajDziecko() dla kadego og z dzieci og.operacja();
Uczestnicy: Komponent (ObiektGraficzny) deklaruje interfejs składanych obiektów implementuje, tam gdzie to moliwe, domylne zachowanie w wypadku interfejsu wspólnego dla wszystkich klas definiuje interfejs umoliwiajcy dostp i zarzdzanie komponentami- dziemi czasami definiuje interfejs umoliwiajcy dostp do rodzica komponentu w strukturze rekurencyjnej i implementuje go, jeli jest taka potrzeba
Lisc (Prostokt, Linia, Tekst) reprezentuje obiekty bdce limi w składanej strukturze definiuje zachowanie obiektów pierwotnych w strukturze Kompozyt (Rysunek) definiuje zachowanie komponentów majcych dzieci przechowuje komponenty bdce dziemi implementuje operacje z interfejsu Komponentu zwizane z dziemi
Klient manipuluje obiektami wystpujcymi w strukturze, wykorzystujc do tego interfejs Komponentu Współpraca: Klienci uywaj interfejsu z klasy Komponent w celu komunikowania si z obiektami składanej struktury. Jeli odbiorca jest liciem, to realizuje operacj, jeli kompozytem, to przesyła dalej.
Konsekwencje: definiuje hierarchie klas grupujce obiekty pierwotne i złoone upraszcza budow klienta ułatwia dodawanie nowych rodzajów komponentów moe sprawi, e projekt bdzie zbyt ogólny trudnoci z ograniczeniem rodzajów obiketów pierwotnych (dynamiczna kontrola typów zamiast statycznej)
Implementacja: jawne odwołania do rodziców ułatwiaj poruszanie si po strukturze i usuwanie komponentu; pomagaj w realizacji ChainOfResponsibility współdzielenie komponentów maksymalne powikszenie interfejsu Komponentu deklarowanie operacji zarzdzania dziemi
uporzdkowanie dzieci jeli kolejno ma znaczenie, to Iterator przechowywanie w pamici podrcznej w celu zwikszenia efektywnoci kto powinien usuwa komponenty? jaka struktura danych jest najlepsza do przechowywania komponentów
Przykłady: Znane zastosowania: Pokrewne wzorce: zwizku komponent-rodzic uywa si te przy stosowaniu ChainOfResponsibility czsto uywany z Decorator Flywieght umoliwia współdzielenie komponentów (ale bez referencji do rodziców)
Iterator moe by uywany do przechodzenia kompozytów Visitor grupuje w jednym miejscu operacje i zachowanie, które w przeciwnym razie byłyby rozproszone w klasach Kompozyt i Lisc