Wzorce projektowe cz. II Wzorce projektowe cz. II 1/35
Wzorce projektowe cz. II 2/35 Iterator Przeznaczenie Wzorzec zapewnia sekwencyjny dostęp do elementów obiektu zagregowanego bez ujawniania jego reprezentacji wewnętrznej Uzasadnienie Obiekt zagregowany, taki jak lista, powinien umożliwiać dostęp do swoich elementów bez ujawniania struktury wewnętrznej. Stosowalność: uzyskanie dostępu do zawartości obiektu-agregatu bez ujawniania jego struktury wewnętrznej, umożliwienie wielokrotnego przechodzenia obiektów-agregatów, zapewnienia jednakowego interfejsu przechodzenia różnych struktur zagregowanych
Wzorce projektowe cz. II 3/35 Iterator Rysunek: Struktura budowy wzorca Iterator
Wzorce projektowe cz. II 4/35 Iterator Uczestnicy: iterator iterator konkretny agregat agregat konkretny Konsekwencje: Możliwość rozmaitego przechodzenia agregatów Iteratory upraszczają interfejs Agregatu W danej chwili może się odbywać więcej niż jedno przechodzenie agregatu
Wzorce projektowe cz. II 5/35 Iterator Znane zastosowania Większość bibliotek klas-kolekcji oferuje iteratory w takiej czy innej postaci, np: C++ Java C#
Wzorce projektowe cz. II 6/35 Iterator przykład kodu Implementacja listy template <c l a s s Item> c l a s s L i s t { p u b l i c : L i s t ( long s i z e = DEFAULT LIST CAPACITY ) ; } ; long Count ( ) const ; Item& Get ( long i n d e x ) const ; //...
Wzorce projektowe cz. II 7/35 Iterator przykład kodu Implementacja klasy abstrakcyjnej Iterator template <c l a s s Item> c l a s s I t e r a t o r { p u b l i c : v i r t u a l void F i r s t ( ) = 0 ; v i r t u a l void Next ( ) = 0 ; v i r t u a l void IsDone ( ) const = 0 ; v i r t u a l Item C u r r e n t I t e m ( ) const = 0 ; protected : I t e r a t o r ( ) ; } ;
Wzorce projektowe cz. II 8/35 Iterator przykład kodu Implementacja podklasy ListIterator klasy Iterator template <c l a s s Item> c l a s s L i s t I t e r a t o r : p u b l i c I t e r a t o r <Item> { p u b l i c : L i s t I t e r a t o r ( const L i s t <Item > a L i s t ) ; v i r t u a l void F i r s t ( ) ; v i r t u a l void Next ( ) ; v i r t u a l void IsDone ( ) const ; v i r t u a l Item C u r r e n t I t e m ( ) const ; p r i v a t e : const L i s t <Item > l i s t ; long c u r r e n t ; } ;
Wzorce projektowe cz. II 9/35 Iterator przykład kodu Implementacja podklasy ListIterator klasy Iterator template <c l a s s Item> L i s t I t e r a t o r <Item >:: L i s t I t e r a t o r ( const L i s t <Item > a L i s t ) : l i s t ( a L i s t ), c u r r e n t ( 0 ) { } template <c l a s s Item> void L i s t I t e r a t o r <Item >:: Next ( ) { c u r r e n t ++; } template <c l a s s Item> Item L i s t I t e r a t o r <Item >:: C u r r e n t I t e m ( ) const { i f ( IsDone ( ) ) { throw I t e r a t o r O u t O f B o u n d s ; } return l i s t >Get ( c u r r e n t ) ; }
Wzorce projektowe cz. II 10/35 Iterator przykład kodu Wykorzystanie iteratorów void P r i n t E m p l o y e e s ( I t e r a t o r <Employee >& i ) { f o r ( i. F i r s t ( ) ;! i. IsDone ( ) ; i. Next ( ) ) { i. C u r r e n t I t e m () > P r i n t ( ) ; } } L i s t <Employee > employees ; //... L i s t I t e r a t o r <Employee > f o r w a r d ( employees ) ; B a c k w a r d L i s t I t e r a t o r <Employee > backward ( employees ) ; P r i n t E m p l o y e e s ( f o r w a r d ) ; P r i n t E m p l o y e e s ( backward ) ;
Wzorce projektowe cz. II 11/35 Singleton Przeznaczenie Gwarantuje, że klasa ma tylko jeden egzemplarz i zapewnia globalny dostęp do niego. Uzasadnienie W wypadku niektórych klas jest niezwykle ważne, by miały tylko jeden egzemplarz, np. w systemie może być wiele drukarek, ale powinien być tylko jeden program buforujący. Stosowalność: klasa musi mieć dokładnie jeden egzemplarz, dostępny dla jej klientów, powinno być możliwe rozbudowywanie tego jedynego egzemplarza przez definiowanie podklas, a klienci powinni móc używać rozszerzonego egzemplarza bez modyfikowania swojego kodu
Wzorce projektowe cz. II 12/35 Singleton Rysunek: Struktura wzorca Singleton
Wzorce projektowe cz. II 13/35 Singleton Uczestnicy Singleton Konsekwencje Kontrolowany dostęp do jednego egzemplarza Mniejsza przestrzeń nazw Możliwe udoskonalanie operacji i reprezentacji Zmienna liczba egzemplarzy Większa elastyczność niż w wypadku operacji statycznych
Wzorce projektowe cz. II 14/35 Singleton Przykład kodu c l a s s S i n g l e t o n { p u b l i c : s t a t i c S i n g l e t o n I n s t a n c e ( ) ; protected : S i n g l e t o n ( ) ; p r i v a t e : s t a t i c S i n g l e t o n i n s t a n c e ; } ; S i n g l e t o n S i n g l e t o n : : i n s t a n c e = 0 ; S i n g l e t o n S i n g l e t o n : : I n s t a n c e ( ) { i f ( i n s t a n c e == 0) { i n s t a n c e = new S i n g l e t o n ; } return i n s t a n c e ; }
Wzorce projektowe cz. II 15/35 Fabryka abstrakcyjna Przeznaczenie Udostępnia interfejs do tworzenia rodzin powiązanych ze sobą lub zależnych od siebie obiektów bez określania ich klas konkretnych. Uzasadnienie Pakiet narzędziowy do tworzenia interfejsów użytkownika obsługiwać ma różne standardy wyglądu i działania. Aby aplikacja była przenośna nie należy zapisywać w niej na stałe określonego sposobu działania widgetów. Tworzenie określających te aspekty egzemplarzy klas w różnych miejscach aplikacji utrudnia późniejszą zmianę jej wyglądu i zachowania.
Wzorce projektowe cz. II 16/35 Fabryka abstrakcyjna Stosowalność: gdy system powinien być niezależny od sposobu tworzenia, składania i reprezentowania obiektów gdy system należy skonfigurować za pomocą jednej z wielu rodzin produktów gdy powiązane obiekty-produkty z jednej rodziny są zaprojektowane do wspólnego użytku i trzeba wymusić korzystanie z tych obiektów gdy programista chce udostępnić klasę biblioteczną produktów i ujawnić jedynie interfejsy, a nie implementacje
Wzorce projektowe cz. II 17/35 Fabryka abstrakcyjna Rysunek: Struktura budowy wzorca Fabryka abstrakcyjna
Wzorce projektowe cz. II 18/35 Fabryka abstrakcyjna Uczestnicy: AbstractFactory obejmuje deklarację interfejsu z operacjami tworzącymi produkty abstrakcyjne ConcreteFactory obejmuje implementację operacji tworzących produkty konkretne AbstractProduct obejmuje deklarację interfejsów dla produktów określonego typu ConreteProduct definiuje obiekt-produkt tworzony przez odpowiadającą mu fabrykę konkretną Client korzysta jedynie z interfejsów zadeklarowanych w klasach AbstractFactory i AbstractProduct
Wzorce projektowe cz. II 19/35 Fabryka abstrakcyjna Konsekwencje: Fabryka abstrakcyjna izoluje klasy konkretne. Fabryka abstrakcyjna ułatwia zastępowanie rodzin produktów. Fabryka abstrakcyjna ułatwia zachowanie spójności między produktami. Fabryka abstrakcyjna utrudnia dodawanie obsługi produktów nowego rodzaju.
Wzorce projektowe cz. II 20/35 Fabryka abstrakcyjna Przykład kodu c l a s s MazeFactory { p u b l i c : MazeFactory ( ) ; v i r t u a l Maze MakeMaze ( ) const { return new Maze ; } v i r t u a l Wall MakeWall ( ) const { return new Wall ; } v i r t u a l Room MakeRoom( i n t n ) const { return new Room( n ) ; } v i r t u a l Door MakeDoor (Room r1, Room r2 ) const { return new Door ( r1, r2 ) ; } } ;
Wzorce projektowe cz. II 21/35 Fabryka abstrakcyjna Przykład kodu Maze MazeGame : : CreateMaze ( MazeFactory& f a c t o r y ) { Maze amaze = f a c t o r y. MakeMaze ( ) ; Room r1 = f a c t o r y. MakeRoom ( 1 ) ; Room r2 = f a c t o r y. MakeRoom ( 2 ) ; Door adoor = f a c t o r y. MakeDoor ( r1, r2 ) ; amaze >AddRoom( r1 ) ; amaze >AddRoom( r2 ) ; } r1 >S e t S i d e ( North, f a c t o r y. MakeWall ( ) ) ; r1 >S e t S i d e ( East, adoor ) ; //... return amaze ;
Wzorce projektowe cz. II 22/35 Fabryka abstrakcyjna Przykład kodu c l a s s EnchantedMazeFactory : p u b l i c MazeFactory { p u b l i c : EnchantedMazeFactory ( ) ; v i r t u a l Room MakeRoom( i n t n ) const { return new EnchantedRoom ( n, C a s t S p e l l ( ) ) ; } v i r t u a l Door MakeDoor (Room r1, Room r2 ) const { return new RoomNeedingSpell ( r1, r2 ) ; } protected : S p e l l C a s t S p e l l ( ) const ; } ;
Wzorce projektowe cz. II 23/35 Metoda wytwórcza Przeznaczenie Określa interfejs do tworzenia obiektów, przy czym umożliwia podklasom wyznaczenie klasy danego obiektu. Metoda umożliwia klasom przekazanie procesu tworzenia egzemplarzy podklasom. Uzasadnienie W platformach klasy abstrakcyjne służą do definiowania i podtrzymywania relacji między obiektami. Platforma często odpowiada także za tworzenie obiektów.
Wzorce projektowe cz. II 24/35 Metoda wytwórcza Stosowalność: gdy w danej klasie nie można z góry ustalić klasy obiektów, które trzeba utworzyć, jeśli programista chce, aby to podklasy danej klasy określały tworzone przez nią obiekty, jeżeli klasy delegują zadania do jednej z kilku podklas pomocniczych, a programista chce zapisać w określonym miejscu informacje o tym, która z tych podklas jest delegatem.
Wzorce projektowe cz. II 25/35 Metoda wytwórcza Rysunek: Struktura budowy wzorca Metoda wytwórcza
Wzorce projektowe cz. II 26/35 Metoda wytwórcza Uczestnicy: Product definiuje interfejs obiektów generowanych przez metodę wytwórczą ConreteProduct obejmuje implementację interfejsu klasy Product Creator obejmuje deklarację metody wytwórczej zwracającej obiekty typu Product; może wywoływać metodę wytwórczą w celu wygenerowania obiektu Product ConreteCreator przesłania metodę wytwórczą, tak aby zwracała egzemplarz klasy ConcreteProduct
Wzorce projektowe cz. II 27/35 Metoda wytwórcza Konsekwencje: Zapewnienie punktów zaczepienia dla podklas Połączenie równoległych hierarchii klas
Wzorce projektowe cz. II 28/35 Metoda wytwórcza implementacja Sparametryzowane metody wytwórcze c l a s s C r e a t o r { p u b l i c : v i r t u a l Product C r e a t e ( P r o d u c t I d ) ; } ; Product C r e a t o r : : C r e a t e ( P r o d u c t I d i d ) { i f ( i d == MINE) return new MyProduct ; i f ( i d == YOURS) return new YourProduct ; // Powtarzanie d l a p o z o s t a l y c h produktow } return 0 ;
Wzorce projektowe cz. II 29/35 Metoda wytwórcza implementacja Wykorzystanie szablonów w celu uniknięcia tworzenia podklas c l a s s C r e a t o r { p u b l i c : v i r t u a l Product C r e a t e ( P r o d u c t I d ) ; } ; template <c l a s s TheProduct> c l a s s S t a n d a r d C r e a t o r : p u b l i c C r e a t o r { p u b l i c : v i r t u a l Product C r e a t e P r o d u c t ( ) ; } ; template <c l a s s TheProduct> Product StandardCreator <TheProduct >:: C r e a t e P r o d u c t ( ) { return new TheProduct ; }
Wzorce projektowe cz. II 30/35 MVC Model-View-Controller Model-Widok-Kontroler: Wzorzec architektury. Oparty o inne wzorce projektowe. Zawiera trzy rodzaje obiektów: model obiekt aplikacji, widok ekranowa reprezentacja modelu, kontroler definiuje sposób, w jaki interfejs użytkownika reaguje na operacje wykonywane przez użytkownika.
Wzorce projektowe cz. II 31/35 Model-Widok-Kontroler Przenosi tradycyjną architekturę aplikacji wsadowych: wejście-przetwarzanie-wyjście do środowiska aplikacji z interfejsem graficznym: kontroler-model-widok
Wzorce projektowe cz. II 32/35 Model-Widok-Kontroler Rysunek: Komunikacja we wzorcu MVC
Wzorce projektowe cz. II 33/35 Model-Widok-Kontroler Scenariusz: Użytkownik wpisuje tekst do okna: 1. Kontroler informuje model, aby ten przechował tekst wprowadzony przez użytkownika. 2. Model powiadamia wszystkie widoki o swojej zmianie. 3. Wszystkie widoki się przerysowują. 4. W czasie ponownego rysowania wszystkie widoki pytają model o wprowadzony tekst.
Wzorce projektowe cz. II 34/35 Model-Widok-Kontroler Rysunek: Diagram sekwencji dla wzorca MVC
Wzorce projektowe cz. II 35/35 W wykładzie wykorzystano materiały Gamma E. i in.: Wzorce projektowe, WNT, Warszawa 2005