Pobieranie prezentacji. Proszę czekać

Pobieranie prezentacji. Proszę czekać

Wzorce Projektowe Bartosz Baliś, Na podstawie Gamma et al. Design Patterns, Elements... John Reekie Design Patterns Pascal Molli, Design Patterns, Architectural.

Podobne prezentacje


Prezentacja na temat: "Wzorce Projektowe Bartosz Baliś, Na podstawie Gamma et al. Design Patterns, Elements... John Reekie Design Patterns Pascal Molli, Design Patterns, Architectural."— Zapis prezentacji:

1 Wzorce Projektowe Bartosz Baliś, Na podstawie Gamma et al. Design Patterns, Elements... John Reekie Design Patterns Pascal Molli, Design Patterns, Architectural Patterns Bruce Eckel, Thinking in Patterns

2 Wprowadzenie Wzorzec projektowy opisuje często powtarzający się problem oraz schemat rozwiązania tego problemu Wzorce są uogólnieniem faktycznych rozwiązań, które były stosowane przez projektantów Wzorce uchwytują specjalistyczne umiejętności ekspertów! Początkujący projektant/programista rozwiązałby problem bez wzorca, ale gorzej Wzorce projektowe dostarczają słownika, którym można opisywać projekt Gamma, Helm, Johnson, Vlissides (Gang of Four) – Design Patterns, Elements of Reusable Object-Oriented Software

3 Siedem warstw architektury * Global architecture Enterprise architecture System architecture Application architecture Macro-architecture Micro-architecture Objects * Mowbray, Malveau, Corba Design Patterns ORB OO architecture Frameworks Subsystem Design patterns OO programming

4 Siedem warstw architektury (c.d.) Architektura globalna: dotyczy koordynacji i komunikacji pomiędzy ogranizacjami Architektura korproracyjna (enterprise): dotyczy koordynacji i komunikacji w obrębie organizacji Architektura systemu: dotyczy koordynacji i komunikacji pomiędzy aplikacjami Architektura aplikacji (Subsystem): dotyczy dostarczania funkcjonalności Makro-architektura (Frameworks): dotyczy powtarzających się aplikacji Mikro-architektura: dotyczy wzorców projektowych Obiekty: dotyczy specyficznych idiomów języka programowania

5 P. Molli 5 Framework (Rama projektowa) Częściowo kompletny (pod-)system, który jest podstawą do stworzenia wielu egzemplarzy systemów. Framework definiuje architekturę dla rodziny (pod-) systemów i dostarcza podstawowych elementów, aby takie systemy stworzyć. Framework definiuje miejsca, w których można wprowadzać adaptacje (implementacje specyficznej funkcjonalności)

6 Dygresja: idiomy języków programowania Tak jak w językach naturalnych: specyficzne sposoby mówienia Np. PL jestem głodny, NIEM Ich habe Hunger PL lepiej późno niż wcale, ANG better late than never Przykład idiomów w C: Nie piszemy: for (i = 1; i <= n; i = i + 1) Ale: for (i = 0; i < n; i++) Idiom jako typ wzorca Niskopoziomowy wzorzec specyficzny dla danego języka programowania. Idiom opisuje jak zaimplementować określony aspekt komponentu (lub powiązanie między komponentami) przy użyciu cech danego języka.

7 Hierarchia wzorców (Bruce Eckel, TIP) Idiom: jak napisać kod w konkretnym języku programowania, aby zrobić konkretną rzecz (np. jak w C iterować po elementach tablicy) Specyficzny projekt (specific design): rozwiązanie, które opracowaliśmy dla danego konkretnego problemu. Może być sprytne, ale nie jest ogólne. Standardowy projekt (standard design): sposób rozwiązania pewnego rodzaju problemu (np. oddzielenie modelu od widoku) Wzorzed projektowy (design pattern): sposób rozwiązania całej klasy podobnych problemów. Zwykle uogólnienie standardowego projektu zastosowanego w kilku problemach.

8 Zasadnicze elementy wzorca projektowego Nazwa wzorca Wchodzi na stałe do słownika opisu archiektury Problem Opisuje, kiedy należy użyć dany wzorzec Rozwiązanie Abstrakcyjny opis projektu, ogólna struktura elementów rozwiązania (klas, obiektów) Konsekwencje Korzyści i koszty użycia wzorca

9 Przykład: model i widoki Model zawiera dane, które mogą być prezentowane na różne sposoby Model komunikuje się z widokami i jeśli dane się zmieniają, prezentacje również Uogólnienie problemu: rozdzielenie obiektów, tak że zmiany w jednym powodują zmiany w dowolnej ilości innych, bez konieczności znajomości dokładnej struktury jednych obiektów przez drugie Wzorzec Obserwator

10 Zestawienie wzorców projektowych Przeznaczenie Konstrukcyjne (Creational) Strukturalne (Structural) Czynnościowe (Behavioral) ZakresKlasa Metoda fabrykująca (Factory Method) AdapterInterpreter Szablon (Template) Obiekt Fabryka (Factory) Fabryka abstrakcji (Abstract Factory) Budowniczy (Builder) Prototyp (Prototype) Singleton Adapter Most (Bridge) Kompozyt (Composite) Dekorator (Decorator) Fasada (Facade) Pośrednik (Proxy) Łańcuch odpowiedzialności (Chain of Responsibility) Polecenie (Command) Iterator Mediator Memento Waga piórkowa (Flyweight) Obserwator (Observer) Stan (State) Strategia (Strategy) Wizytator (Visitor)

11 Typowe problemy, w których korzystnie jest użyć wzorców Tworzenie obiektu poprzez jawne określenie klasy Jawne określanie klasy gdy tworzymy obiekt wiąże nas z konkretną implementacją, zamiast z konkretnym interfejsem, co może utrudnić zmiany w przyszłości. Aby tego uniknąć, należy tworzyć obiekty w metodami pośrednimi. Wzorce: Fabryka abstrakcji, Metoda fabrykująca, Prototyp Zależność od określonych operacji Gdy bezpośrednio określamy konkretną operację, jesteśmy skazani na jeden sposób spełnienia żądania. Jeśli tego unikniemy, łatwiej będzie zmienić sposób obsługi żądania zarówno na poziomie kompilacji, jak i uruchomienia. Wzorce: Łańcuch odpowiedzialności, Polecenie

12 Typowe problemy (2) Zależność od platformy programowej i sprzętowej Zewnętrzne interfejsy do systemu lub aplikacji (API) różnią się na różnych platformach sprzętowych i programowych. Oprogramowanie, które jest uzależnione od danej platformy trudniej przenosi się na inne platformy, a nawet może być trudne do uaktualniania na macierzystej platformie. Zatem staramy się projektować tak, aby zminimializować zależności od platformy. Wzorce: Fabryka abstrakcji, Most Zależność od reprezentacji lub implementacji obiektu Klienci, którzy wiedzą jak obiekt jest reprezentowany, zapisywany czy implementowany i z tej wiedzy korzystają, muszą być modyfikowani, gdy obiekt jest zmieniany. Ukrywanie takich informacji zapobiega konieczności kaskadowych zmian. Wzorce: Fabryka abstrakcji, Most, Memento, Pośrednik

13 Typowe problemy (3) Zależność od algorytmu Algorytmy są często rozszerzane, optymalizowane i zmieniane. Obiekty, które są zależne od konkretnego algorytmu będą musiały być zmienione, gdy algorytm ulegnie zmianie. Dlatego należy projektować tak, aby wyeliminować zależność od konkretnego algorytmu. Wzorce: Budowniczy, Iterator, Strategia, Szablon metod, Wizytator Ścisłe połączenie (tight coupling) Ściśle połączone klasy są trudne do ponownego użycia osobno. Ścisłe połączenie prowadzi do systemów monolitycznych, gdzie jedna zmiana pociąga zmiany w wielu innych miejscach. Luźne połączenie (loose coupling) sprzyja ponownemu użyciu, przenośności i rozszerzalności. Przy pomocy wzorców projektowych można zmniejszać ścisłość połączenia w systemie. Wzorce: Fabryka abstrakcji, Most, Łańcuch odpowiedzialności, Polecenie, Fasada, Mediator, Obserwator

14 Typowe problemy (4) Rozszerzanie funkcjonalności poprzez tworzenie klas potomnych Rozszerzanie funkcjonalności poprzez klasy potomne niesie ze sobą szereg trudności, konieczność dokładnej znajomości klasy podstawowej. Np. przesłonięcie jednej metody może wymagać przesłonięcia innej. Alternatywą dla tworzenia klas potomnych jest kompozycja obiektów. Z drugiej strony używanie kompozycji utrudnia zrozumienie projektu. Wiele wzorców projektowych umożliwia rozszerzeanie funkcjonalności poprzez jednokrotne tworzenie klasy potomnej i kompozycję jej instancji z istniejącymi klasami. Wzorce: Most, Łańcuch odpowiedzialności, Kompozyt, Dekorator, Obserwator, Strategia Brak możliwości wygodnej modyfikacji klasy Czasem istnieje konieczność modyfikacji klasy, gdy nie da się tego zrobić w sposób wygodny (nie ma kodu źródłowego, trzeba byłoby modyfikować wiele klas potomnych, itp.) Wzorce projektowe pozwalają na modyfikacje klasy w takich sytuacjach. Wzorce: Adapter, Dekorator, Wizytator

15 Wzorzec projektowy vs. Framework Wzorce są bardziej niskopoziomowe niż frameworki Framework zwykle składa sie z wielu wzorców: Fabryka Strategia Kompozyt Obserwator

16 Wzorce konstrukcyjne

17 Singleton Gwarantuje, że dana klasa ma tylko jeden obiekt (instancję) i zapewna globalny sposób dostępu do tego obiektu. Obiekt stworzony wg tego wzorca może zastąpić zmienną globalną. Podejście Klasę typu Singleton należy uczynić odpowiedzialną za tworzenie, inicjalizację, dostęp i ew. zmiany obiektów. Sam obiekt musi być jej składnikiem typu private static, a funkcja inicjalizacji i dostępu – public static Np. prezydent USA – istnieje co najwyżej jeden Jest też określany jako idiom

18 class Singleton { private Singleton s; private int i; private Singleton(int x) { i = x; } public static Singleton getReference() { if (s == null) s = new Singleton(2); return s; } public int getValue() { return i; } public void setValue(int x) { i = x; } } Singleton – przykład

19 Wzorzec ten w zależności od dostarczonych danych, zwraca instancję jednej z możliwych klas. Najczęściej zwracane klasy wywodzą się z tej samej klasy podstawowej i mają takie same metody, ale każda z nich wykonuje swoje zadania w inny sposób i jest zoptymalizowana dla innego rodzaju danych. Rozwinięciem tego wzorca jest fabryka abstrakcyjna – struktura gdzie istnieje klasa - fabryka bazowa i jej różne podklasy – specyficzne fabryki. Fabryka

20 Fabryka – schemat

21 abstract class Shape { public abstract void draw(); public abstract void erase(); public static Shape factory(String type) { if(type.equals("Circle")) return new Circle(); if(type.equals("Square")) return new Square(); throw new RuntimeException( "Bad shape creation: " + type); } class Circle extends Shape { Circle() {} // Package-access constructor public void draw() { System.out.println("Circle.draw"); } public void erase() { System.out.println("Circle.erase"); } public class ShapeFactory1 extends TestCase { String shlist[] = { "Circle", "Square", "Square", "Circle", "Circle", "Square" }; List shapes = new ArrayList(); public void test() { Iterator it = Arrays.asList(shlist).iterator(); while(it.hasNext()) shapes.add(Shape.factory((Stri ng)it.next())); it = shapes.iterator(); while(it.hasNext()) { Shape s = (Shape)it.next(); s.draw(); s.erase(); } Fabryka – przykład

22 Fabryka abstrakcyjna Cel Otrzymanie jednej z wielu związanych ze sobą klas obiektów, z których każdy może na żądanie zwrócić wiele innych obiektów

23 Fabryka abstrakcyjna – schemat

24 Fabryka (abstrakcyjna) – kiedy używać System ma być niezależny od tego jak jego produkty są tworzone, komponowane i reprezentowane System ma być skonfigurowany z jedną z wielu rodzin produktów Rodzina obiektów powiązanego produktu jest zaprojektowana do wspólnego używania i chcemy to wymusić Chcemy dostarczyć bibliotekę produktów, ale chcemy ujawnić tylko ich interfejsy, nie implementacje

25 Wzorce strukturalne

26 Adapter Konwertuje interfejs jednej klasy na interfejs innej klasy, którego spodziewa się klient Adapter umożliwia współpracę niekompatybilnych klas

27 P. Molli 27 Adapter – struktura

28 P. Molli 28 Adapter – przykład

29 Konstrukcja hierarchii całość-część Upraszcza interfejs klienta do liści/kompozytów Łatwiej dodawać nowe komponenty Wzorzec kompozytu pozwala na jednolite traktowanie komponentów i obiektów z nich złożnych poprzez specyfikację ich wspólnego interfejsu. Przykład: zapis działania matematycznego, składa się ono z liczb, symboli operatorów i nawiasów; także przepis kuchenny, jeśli za komponenty uznamy poszczególne składniki. Kompozyt

30 Kompozyt – struktura

31 P. Molli 31 Kompozyt – przykład

32 P. Molli 32 Kompozyt – przykład (obiekty)

33 Fasada Jednolity interfejs do zbioru interfejsów w systemie Ukrywa i oddziela podsystemy przed klientami Facade Client

34 Fasada – przykład Entity CompositeEntityAtomicEntity PortRelation BufferedRelation Graph SchematicEditor Interfejs do silnika symulacji Actor Director 0..* 2 Token

35 Most Oddziela abstrakcję od implementacji, tak że mogą one zmieniać się niezależnie od siebie Zwiększa łatwość rozbudowy Ukrywa przed klientem szczegóły implementacji

36 Most – struktura

37 Most – przykład

38 Most – kiedy używać Gdy chcemy uniknąć trwałego połączenia abstrakcji i jej implementacji. Np. implementacja ma być wybrana lub zmieniona w trakcie wykonania Zarówno abstrakcje jak i implementacje powinny być rozszerzalne przez tworzenie klas potomnych. Most pozwala na łączenie różnych abstrakcji z implementacjami i ich niezależną rozbudową Zmiany w implementacji nie powinny mieć wpływu na klientów (nie powinno być konieczności ich rekompilacji) Gdy chcemy używać jednej implementacji w wielu obiektach jednocześnie (np. przez licznik referencji) i ma to być ukryte przed klientem Prosty przykład: wiele obiektów String może odnosić się do tego samego łańcucha w pamięci

39 Wzorce czynnościowe

40 Stan pozwala obiektowi zmienić zachowanie gdy zmieni się jego stan wewnętrzny

41 Stan – przykład

42 Stan – kiedy używać Zachowanie obiektu jest zależne od stanu, w jakim się znajduje i musi być ono zmieniane w trakcie wykonania Operacje zawierają wielokrotne instrukcje warunkowe, zależne od stanu obiektu (zwykle wartości jakiejś zmiennej typu wyliczeniowego). Często wiele operacji będzie zawierać tę samą strukturę instrukcji warunkowych. Stan pozwala umieścić każde odgałęzienie instrukcji warunkowej w osobnej klasie, co pozwala na traktowanie stanu jako osobnego obiektu, który może się zmieniać niezależnie od innych obiektów.

43 Strategia Strategy Operation() ConcreteStrategy2 Operation() Context Pozwala na podmianę algorytmów Alternatywa dla tworzenia klas pochodnych Wybór implementacji w trakcie wykonania Zwiększa złożoność w trakcie wykonania ContextInterface() ConcreteStrategy1 Operation()

44 P. Molli 44 Strategia – przykład

45 Strategia – kiedy używać Wiele powiązanych klas różni się tylko zachowaniem. Strategia pozwala na możliwość konfiguracji klasy z jednym wybranym zachowaniem Potrzebujemy różnych odmian algorytmu Algorytm używa danych, o których klient powinien wiedzieć. Strategia pozwala uniknąć ujawniania złożonych specyficznych dla algorytmu struktur danych Klasa definiuje wiele zachowań, które pojawiają się w wielokrotnych instrukcjach warunkowych. Zamiast nich można każdą gałąź instrukcji warunkowej przenieść do osobnej klasy strategii

46 Dalsza lektura FAQ Bruce Eckel, Thinking in Patterns Podstawowe wzorce Patterns/default.htm Patterns/default.htm Patterns home page


Pobierz ppt "Wzorce Projektowe Bartosz Baliś, Na podstawie Gamma et al. Design Patterns, Elements... John Reekie Design Patterns Pascal Molli, Design Patterns, Architectural."

Podobne prezentacje


Reklamy Google