1 Inżynieria oprogramowania Wzorce strukturalne WWW: http://www.fizyka.umk.pl/~jacek/dydaktyka/inzynieria/index.html Jacek Matulewski Instytut Fizyki, UMK WWW: http://www.fizyka.umk.pl/~jacek E-mail: [email protected] semestr letni 2016
2 Główna lektura 1 Głównym materiałem źródłowym jest książka tzw. gangu czworga pt. „Wzorce projektowe”.
3 Główna lektura 1 Głównym materiałem źródłowym jest książka tzw. gangu czworga pt. „Wzorce projektowe”.
4 Główna lektura 2 Dodatkowo wykorzystamy adaptacje do C# wzorców G4 opisane w książce S. J. Metskera
5 Wzorce strukturalne Wzorce dotyczące relacji między klasami, rozwiązujące typowe problemy systemów z wieloma klasami: Adapter (Adapter) Dekorator (Decorator) Fasada (Facade) Kompozyt (Composite) Most (Bridge) Pełnomocnik (Proxy) Pyłek (Flyweight)
6 Adapter (Adapter) Założenia (adapter klasowy): Client używa obiektów pochodnych względem Target. Chcemy użyć także Adaptee, ale ma inny interfejs. Tworzymy Adapter typu Target (relacja jest), który korzysta z obiektu Adaptee (wielodziedziczenie). http://www.frederikprijck.net/external-libraries-and-the-adapter-pattern/http://zenit.senecac.on.ca/wiki/index.php/Adapter
7 Adapter (Adapter) Implementacja Nowy kod: funkcja WIoF(WielokątForemny*) Istniejący kod: klasa Prostokąt Chcemy użyć nowej funkcji dla istniejącej klasy. W.NET: interfejs określający wymagania klienta (ITarget) Nazwy używane w kontekście tego wzorca: WielokątForemny – Target, element docelowy WyświetlInformacjeOFigurze – Client Prostokąt – Adaptee, klasa dostosowywana ProstokątForemny – Adapter, kl. dostosowująca
8 Adapter (Adapter) Adapter klasowy i adapter obiektowy – Adapter obiektowy nie adaptuje klasy (dziedziczeniem prywatnym), a obiekt tej klasy przekazywany przez argument konstruktora – Adapter klasowy nie działa dla klas potomnych Adaptee, a obiektowy – tak – Adapter klasowy może przesłaniać funkcje Adaptee, w adapterze obiektowym to jest trudne Adapter dwukierunkowy (przezroczystość) Adaptery dołączalne – umieją dynamicznie, na podstawie dostarczonych danych, pobierać dane z Adaptee, którego typ nie jest ustalony przy kompilacji
9 Dekorator (Decorator) Założenia: Chcemy dodać funkcjonalność/obowiązek do jednego obiektu, bez zmieniania jego klasy. Włożymy go w lekką otoczkę, która doda funkcję. http://zenit.senecac.on.ca/wiki/index.php/Adapter
10 Dekorator (Decorator) Implementacja Dekorator to klasa dziedzicząca z Component (interfejs) i mająca Component jako pole (na przechowanie Concrete component). Udostępnia metody i pola tego pola modyfikując je lub dodając. Nazwy używane w kontekście tego wzorca: Napój – Component Herbata, Kawa – Concrete component NapójZDodatkiem – Decorator NapójZPlastremCytryny – Concrete decorator
11 Fasada (Facade) Założenia: Dodatkowa klasa udostępniająca metody wyższego poziomu złożone z wielu wywołań metod biblioteki lub podsystemu klas. Tworzy ujednolicony prosty interfejs. http://www.tonymarston.net/php-mysql/design-patterns.html#facade (na podstawie rysunku z G4)
12 Fasada (Facade) Przykład: Realizowanie zamówień: 1. Sprawdzenie dostępności towaru 2. Wypełnienie formularza 3. Zapłacenie rachunku 4. Dostarczenie Fasada: Złóż zamówienie Nazwy używane w kontekście tego wzorca: NapojeMenu – Facade Herbata, NapójZCytryną, itd. - klasy podsystemu
13 Kompozyt (Composite) Cel: Pozwala na budowanie z obiektów struktury drzewa (hierarchia część-całość) http://zenit.senecac.on.ca/wiki/index.php/Composite
14 Kompozyt (Composite) Przykład: Nazwy używane w kontekście tego wzorca: IPracownik – Component Pracownik – Leaf Kierownik – Composite funkcja main – Client
15 Kompozyt (Composite) Zalety: Nadrzędny element (korzeń drzewa) reprezentuje wszystkie elementy podrzędne (uproszczenie interfejsu, a więc i kodu klienta) Można definiować wiele liści (np. klasy potomne po Pracownik) i wiele kompozytów (np. klasy potomne po kierownik) – możliwość rozszerzania zbioru klas Kompozyty z cyklami: Zwykle kompozyt kojarzymy z drzewami, ale może zawierać cykle – należy to uwzględnić przy korzystaniu z rozwiązań bazujących na rekurencjach.
16 Kompozyt (Composite) Zadanie domowe: Zadeklarować w interfejsie IPracownik i zaimplementować w klasie Pracownik metodę Count zliczającą liczbę elementów w podstukturze. Uwzględnić możliwość istnienia cykli w strukturze kompozytu (gdy pracownik staje się np. dziekanem).
17 Kompozyt (Composite) Konkursy: 1.Zmodyfikować kod w taki sposób, aby metoda WyświetlInformacje lepiej pokazywała strukturę obiektów (drzewo). Jak przekazać stopień zagnieżdżenia? 2.Zaimplementować w klasie Kierownik interfejs IEnumerable, który umożliwia umożliwić pobranie iteratora ( IEnumerator ) pozwalającego na przeglądanie całej struktury podwładnych (w dowolnym poziomie zagnieżdżenia). Uwzględnić ewent. obecność cykli.
18 Most (Bridge) Cel: Rozdziela interfejs od implementacji, także dziedziczenia (bogate uchwyty do klas – handle/body class) http://en.wikipedia.org/wiki/Bridge_pattern
19 Most (Bridge) Założenia: Skrzyżowanie dwóch lub więcej katerogii (np. klasy różnego typu implementowane dla różnych platform) powoduje „zoo” klas i zależności. Jeżeli oddzielimy i ukryjemy implementacje, to podział samym „interfejsów” klas jest prostszy. Most to nazwa dla relacji między abstrakcją (ogólnym interfejsem) a abstrakcyjną implementacją Dobry przykład: figury rysowane w różnych systemach graficznych (podział figur vs API do ich rysowania) Nasz przykład: relacja pilot-telewizor(y)
20 Most (Bridge) Przykład: Nazwy używane w kontekście tego wzorca: Shape – Abstraction Rectangle, Circle – Refined Abstraction Drawing – Implementor WinDrawing, XDrawing – Concrete Implementor http://www.informit.com/articles/article.aspx?p=1398603&seqNum=4
21 Pełnomocnik (Proxy) Cel: „Cieńki” pełnomocnik „grubej” klasy (inny kontekst niż most) http://www.slideshare.net/pickerweng/android-camera-architecture-8098156 (na bazie G4)
22 Pełnomocnik (Proxy) Cel: „Cieńki” pełnomocnik „grubej” klasy (inny kontekst niż most) http://www.slideshare.net/pickerweng/android-camera-architecture-8098156 (na bazie G4)
23 Pełnomocnik (Proxy) Przykład: Nazwy używane w kontekście tego wzorca: ŚrodkiPłatności - Subject CzekBankowy – Proxy Gotówka, PieniądzeWBanku – Real Subject https://sourcemaking.com/design_patterns/proxy
24 Pełnomocnik (Proxy) Założenia: Pełnomocnik wirtualny - odraczanie kosztów związanych z ewentualnym tworzeniem „grubego” obiektu (por. leniwa inicjacja) Zdalny pełnomocnik obiektu z innego procesu lub komp. Pośrednik zabezpieczający – celem jest zabezpieczenie obiektu lub programu (sprawdzanie blokad), a nie ograniczenie użycia zasobów Inteligentne wskaźniki (referencje) – realizują także powyższe cele Pośrednik danych – częsty przykład, unifikacja
25 Pełnomocnik (Proxy) Leniwa inicjacja class MathProxy : public IMath { private: Math* math; Math* getMathInstance() { if (!math) math = new Math(); return math; } public: MathProxy() :math(NULL) {}
26 Pyłek (Flyweight) Cel: Zmniejszyć zużycie pamięci zmarnowanej na obsługę wielu powielonych obiektów (por. prosta kompresja) http://flylib.com/books/en/2.505.1.19/1/ (na bazie G4)
27 Pyłek (Flyweight) Warunki stosowania: Aplikacja korzysta z dużej liczby powtarzających się obiektów Koszty przechowywania tych obiektów są duże Stan obiektu można zapisać poza nim Nie ma porównywania obiektów Porównaj z najprostszą metodą kompresji przez kodowanie słownikowe (LZ/Lempel-Ziv, ZIP, RAR, PNG), słownik statyczny (określony przez klasy pyłków)
28 Pyłek (Flyweight) Przykład: Nazwy używane w kontekście tego wzorca: Znak – Flyweight ZnakA, ZnakB,... – ConcreteFlyweight FabrykaZnaków – FlyweightFactory main, document – Client http://flylib.com/books/en/2.505.1.19/1/ (na bazie G4)