Wzorce projektowe cz. I Wzorce projektowe cz. I 1/33
Wzorce projektowe cz. I 2/33 Historia Wzorce projektowe: wywodzą się z wzorców projektowych w architekturze termin wzorca projektowego wprowadzony do inżynierii oprogramowania Kenta Becka oraz Warda Cunninghama w 1987 termin wzorca projektowego spopularyzowany przez Bandę Czterech w 1995 roku dzięki książce Inżynieria oprogramowanie: Wzorce projektowe
Wzorce projektowe cz. I 3/33 Wzorce rozwiązań Wzorce projektowe: dostarczają wypróbowane rozwiązania dla problemów algorytmy nie są wzorcami projektowymi, gdyż rozwiązują problemy obliczeniowe, a nie projektowe wzorce projektowe stanowią abstrakcyjny opis zależności między klasami
Wzorce projektowe cz. I 4/33 Elementy wzorca Minimalny opis wzorca składa się z: nazwy wzorca rozwiązywanego problemu rozwiązania konsekwencji
Wzorce projektowe cz. I 5/33 Klasyfikacja Podział wzorców według tego co wzorzec robi kreacyjne (konstrukcyjne) strukturalne czynnościowe Podział wzorców według ich zakresów klasowe obiektowe
Wzorce projektowe cz. I 6/33 Wzorce kreacyjne Budowniczy (obiektowy) Fabryka abstrakcyjna (obiektowy) Metoda wytwórcza (klasowy) Prototyp (obiektowy) Singleton (obiektowy)
Wzorce projektowe cz. I 7/33 Wzorce strukturalne Adapter (klasowy oraz obiektowy) Dekorator (obiektowy) Fasada (obiektowy) Kompozyt (obiektowy) Most (obiektowy) Pełnomocnik (obiektowy) Pyłek (obiektowy)
Wzorce projektowe cz. I 8/33 Wzorce czynnościowe Interpreter (klasowy) Iterator (obiektowy) Łańcuch zobowiązań (obiektowy) Mediator (obiektowy) Metoda szablonowa (klasowy) Obserwator (obiektowy) Odwiedzający (obiektowy) Pamiątka (obiektowy) Polecenie (obiektowy) Stan (obiektowy) Strategia (obiektowy)
Wzorce projektowe cz. I 9/33 Projektowanie z wykorzystaniem wzorców Kroki: Określenie zbioru wzorców występujących w dziedzinie problemu Dla uzyskanego zbioru wzorców: wybranie wzorca, który określa kontekst pozostałych wzorców zastosowanie tego wzorca do ogólnej koncepcji rozwiązania; zidentyfikowanie dodatkowych wzorców, które mogły się ujawnić i dodanie ich do analizowanego problemu; wykonanie powyższych kroków dla każdego wzorca należącego do zbioru, o ile nie był on jeszcze analizowany. Dodanie szczegółów, Zdefiniowanie metod i klas.
Strategia Przeznaczenie sprawia, że możliwe staje się zmienianie algorytmu niezależnie od używających go klientów Uzasadnienie Np. jest kilka algorytmów dzielenia tekstu na wiersze. Nie powinno się sztywno kodować tych algorytmów w używanych klasach. Stosowalność wiele powiązanych klas różni się tylko zachowaniem potrzebne są różne warianty jakiegoś algorytmu w algorytmie używane są dane, o których klient nie powinien wiedzieć klasa definiuje wiele zachowań, które w operacjach są uwzględnione w postaci wielokrotnych instrukcji warunkowych Wzorce projektowe cz. I 10/33
Wzorce projektowe cz. I 11/33 Strategia Rysunek: Struktura
Wzorce projektowe cz. I 12/33 Strategia Uczestnicy Strategia StrategiaKonkretna Kontekst Współpraca Klasy Strategia i Kontekst współdziałają w celu zaimplementowania wybranego algorytmu Kontekst przekazuje żądania od klientów do swojej strategii
Wzorce projektowe cz. I 13/33 Strategia Konsekwencje rodziny powiązanych ze sobą algorytmów alternatywa dla tworzenia podklas strategie eliminują instrukcje warunkowe wybór implementacji klienci muszą być świadomi istnienia różnych strategii koszty związane z komunikacją między Strategią a Kontekstem zwiększona liczba obiektów
Wzorce projektowe cz. I 14/33 Strategia Przykład implementacji template <c l a s s AStrategy> c l a s s Context { v o i d Operation ( ) { t h e S t r a t e g y. DoAlgorithm ( ) ; } //... private : AStrategy thestrategy ; }; c l a s s MyStrategy { public : v o i d DoAlgorithm ( ) ; }; Context<MyStrategy> acontext ;
Adapter Przeznaczenie przekształca interfejs klasy na taki, jakiego klienci oczekują. Uzasadnienie Czasami klasa z pakietu narzędziowego, zaprojektowanego do wielokrotnego użytku nie jest ponownie używana tylko dlatego, że jej interfejs nie pasuje do interfejsu wymaganego przez aplikację. Stosowalność chęć wykorzystania istniejącej klasy, mimo iż jej interfejs nie jest odpowiedni chęć utworzenia klasy wielokrotnego użytku, która współpracuje z niepowiązanymi ze sobą klasami (tylko adapter obiektów) potrzeba użycia kilku istniejących podklas Wzorce projektowe cz. I 15/33
Wzorce projektowe cz. I 16/33 Adapter Rysunek: Struktura adaptera klas Rysunek: Struktura adaptera obiektów
Wzorce projektowe cz. I 17/33 Adapter Uczestnicy Cel Klient Adaptowany Adapter Współpraca Klienci wywołują operacje egzemplarza Adaptera. Z kolei adapter wywołuje operacje adaptowane, umożliwiające spełnienie żądania.
Wzorce projektowe cz. I 18/33 Adapter Konsekwencje Adaptery klas: nie będzie działał, gdy będziemy chcieli zaadoptować klasę oraz jej wszystkie podklasy umożliwia Adapterowi przedefiniowanie części zachowania Adaptowanego, gdyż Adapter jest jego podklasą wprowadza tylko jeden obiekt, aby dostać się do adaptowanego Adaptery obiektów umożliwia jednemu Adapterowi działanie z wieloma Adaptowanymi utrudnia przedefiniowanie zachowania Adaptowanego
Wzorce projektowe cz. I 19/33 Adapter Rysunek: Przykład wykorzystania adaptera
Wzorce projektowe cz. I 20/33 Adapter Przykład kodu c l a s s TextShape : public Shape { public : TextShape ( TextView ) ; v i r t u a l v o i d BoundingBox ( Point& bottomleft, Point& topright ) const ; v i r t u a l b o o l IsEmpty ( ) c o n s t ; v i r t u a l M a n i p u l a t o r C r e a t e M a n i p u l a t o r ( ) c o n s t ; private : TextView t e x t ; }; TextShape : : TextShape ( TextView t ) { t e x t = t ; }
Wzorce projektowe cz. I 21/33 Adapter Przykład kodu v o i d TextShape : : BoundingBox ( Point& bottomleft, Point& topright ) c o n s t { Coord bottom, l e f t, width, h e i g h t ; t e x t >G e t O r i g i n ( bottom, l e f t ) ; text >GetExtent ( width, height ) ; b o t t o m L e f t = P o i n t ( bottom, l e f t ) ; topright = Point ( bottom + height, l e f t + width ) ; } b o o l TextShape : : IsEmpty ( ) c o n s t { r e t u r n t e x t >IsEmpty ( ) ; } Manipulator TextShape : : CreateManipulator ( ) c o n s t { r e t u r n new T e x t M a n i p u l a t o r ( t h i s ) ; }
Wzorce projektowe cz. I 22/33 Obserwator Przeznaczenie gdy jeden obiekt zmienia stan, wszystkie obiekty odeń zależne powinny być automatycznie aktualizowane. Uzasadnienie Typowym efektem ubocznym dzielenia systemu na współpracujące klasy jest potrzeba utrzymywania spójności między powiązanymi obiektami. Stosowalność jakaś abstrakcja ma dwa aspekty, jeden zależny od drugiego zmiana jednego obiektu wymaga zmiany innych obiekt powinien móc powiadamiać inne obiekty, nie przyjmując żadnych założeń co do tego, co te obiekty reprezentują
Wzorce projektowe cz. I 23/33 Obserwator Rysunek: Struktura
Wzorce projektowe cz. I 24/33 Obserwator Uczestnicy Obserwowany Obserwator ObserwowanyKonkretny ObserwatorKonkretny Współpraca ObserwowanyKonkretny zawsze powiadamia swoich obserwatorów, gdy wystąpi zmiana Po otrzymaniu powiadomienia o zmianie, która wystąpiła w obserwowanykonkretny, obserwatorkonkretny może go zapytać o informacje dotyczące tej zmiany
Wzorce projektowe cz. I 25/33 Obserwator Konsekwencje Abstrakcyjne połączenie między Obserwowanym a Obserwatorem Wsparcie dla rozsyłania komunikatów Nieoczekiwane uaktualnienia
Wzorce projektowe cz. I 26/33 Obserwator Przykład kodu c l a s s S u b j e c t ; c l a s s O b s e r v e r { public : v i r t u a l O b s e r v e r ( ) ; v i r t u a l void Update ( Subject thechangedsubject ) = 0 ; protected : O b s e r v e r ( ) ; }; c l a s s S u b j e c t { public : v i r t u a l S u b j e c t ( ) ; v i r t u a l v o i d Attach ( O b s e r v e r ) ; v i r t u a l v o i d Detach ( O b s e r v e r ) ; v i r t u a l v o i d N o t i f y ( ) ; protected : S u b j e c t ( ) ; private : l i s t <O b s e r v e r > o b s e r v e r s ; };
Wzorce projektowe cz. I 27/33 Obserwator Przykład kodu v o i d Subject : : Attach ( Observer o ) { o b s e r v e r s. p u s h b a c k ( o ) ; } v o i d Subject : : Detach ( Observer o ) { o b s e r v e r s. remove ( o ) ; } v o i d S u b j e c t : : N o t i f y ( ) { l i s t <O b s e r v e r >:: i t e r a t o r i ; f o r ( i= o b s e r v e r s. b e g i n ( ) ; i!= o b s e r v e r s. end ( ) ; ++i ) { ( i) >Update ( t h i s ) ; } } c l a s s ClockTimer : public S u b j e c t { public : ClockTimer ( ) ; v i r t u a l i n t GetHour ( ) ; v i r t u a l i n t GetMinute ( ) ; v i r t u a l i n t GetSecond ( ) ; v o i d Tick ( ) ; }; v o i d ClockTimer : : Tick ( ) { // update i n t e r n a l time k e e p i n g s t a t e //... N o t i f y ( ) ; }
Wzorce projektowe cz. I 28/33 Kompozyt Przeznaczenie składa obiekty w struktury drzewiaste reprezentujące hierarchię typu część-całość Uzasadnienie Edytor graficzny umożliwia tworzenie skomplikowanej figury geometrycznej z figur prostych. Stosowalność chęć przedstawienia hierarchii obiektów część całość klienci mogą ignorować różnicę między pojedynczymi obiektami i ich złożeniami
Wzorce projektowe cz. I 29/33 Kompozyt Rysunek: Struktura
Wzorce projektowe cz. I 30/33 Kompozyt Uczestnicy Komponent Liść Kompozyt Klient Współpraca Klienci używają interfejsu z klasy Komponent w celu komunikowania się z obiektami występującymi w składanej strukturze
Wzorce projektowe cz. I 31/33 Kompozyt Konsekwencje definiuje hierarchie klas grupujące obiekty pierwotne i złożone upraszcza budowę klienta ułatwia dodawanie nowych komponentów może sprawić, że projekt będzie zbyt ogólny
Wzorce projektowe cz. I 32/33 Kompozyt Przykład implementacji c l a s s Composite ; c l a s s Component { public : //... v i r t u a l Composite GetComposite ( ) { r e t u r n 0 ; } }; c l a s s Composite : public Component { public : v o i d Add ( Component ) ; //... v i r t u a l Composite GetComposite ( ) { r e t u r n t h i s ; } }; c l a s s L e a f : public Component { //... }; Composite acomposite = new Composite ; Leaf aleaf = new Leaf ; Component acomponent ; Composite t e s t ; acomponent = acomposite ; i f ( t e s t = acomponent >GetComposite ( ) ) { test >Add (new Leaf ) ; } acomponent = aleaf ; i f ( t e s t = acomponent >GetComposite ( ) ) { test >Add (new Leaf ) ; }
Wzorce projektowe cz. I 33/33 W wykładzie wykorzystano materiały Gamma E. i in.: Wzorce projektowe, WNT, Warszawa 2005,