Pobierz prezentację
Pobieranie prezentacji. Proszę czekać
OpublikowałPrzemysław Sitarski Został zmieniony 11 lat temu
1
Wzorce Projektowe Michał Gryglicki
2
Plan prezentacji Czego się spodziewałem? Czym są? Do czego służą?
Ogólny podział wzorców? Omówienie przykładowych wzorców: Dekorator Fasada Pełnomocnik Pyłek Stan Bibliografia
3
Wstęp Czego się spodziewałem? Co spotkałem? Jakiejś magii…
Wielkich nowości… Co spotkałem? Znajome pomysły…
4
Czym są wzorce projektowe?
„Wzorzec projektowy pozwala uczyć się na sukcesach innych zamiast nauki na własnych błędach” (Mark Johnson) Sprawdzone rozwiązania efektywność Najlepsze projekty jakość Dobre praktyki skalowalność
5
Czym są wzorce projektowe?
„Opisem komunikujących się obiektów i klas, które są specjalnie wykonane, aby rozwiązać ogólny problem przy dokładnie określonym kontekście” (GangOfFour, 1994) „Powracającym rozwiązaniem zagadnień projektowych, z którymi wciąż się spotykamy” (Alpert, 1994) „Zbiorem reguł opisujących, w jaki sposób osiągnąć pewne cele w dziedzinie programowania” (Pree, 1994)
6
Czym są wzorce projektowe?
„Każdy wzorzec opisuje problem, który ciągle na nowo pojawia się w naszym otoczeniu i opisuje rdzeń jego rozwiązania w taki sposób, że można go używać milion razy i nigdy w ten sam sposób.” (Christopher Alexander)
7
Elementy wzorca Nazwa wzorca Problem Rozwiązanie Konsekwencje
Odzwierciedla problem, rozwiązanie i konsekwencje danego wzorca Problem Opisuje zagadnienie i kontekst wystąpienia wzorca Rozwiązanie Opisuje elementy tworzące projekt, ich relacje, odpowiedzialności oraz współpracę Konsekwencje Rezultaty zastosowania wzorca – korzyści i straty
8
Po co nam wzorce? Zapobiegają ponownemu wymyślaniu kodu zaprojektowanemu już przez kogoś innego Zmniejszają liczbę popełnionych błędów Zapewniają kod łatwo rozszerzalny Ułatwiają zrozumienie kodu Ułatwiają komunikację w zespole Nazwa identyfikuje wzorzec
9
Podział wzorców Konstrukcyjne Strukturalne Behawioralne
wykorzystuje się je do pozyskania obiektów zamiast bezpośredniego tworzenia instancji klasy programy zyskują na elastyczności, gdyż można decydować, jaki typ obiektu ma zostać utworzony w danym przypadku Strukturalne pomagają łączyć obiekty w większe struktury Behawioralne charakteryzują sposób, w jaki klasy lub obiekty oddziaływują i dzielą odpowiedzialności pomagają definiować przepływ danych w złożonym programie
10
Katalog wzorców Przeznaczenie Konstrukcyjne Strukturalne Behawioralne
Zakres Klasa Metoda wytwórcza Adapter Interpreter Metoda szablonowa Obiekt Budowniczy Fabryka abstrakcyjna Prototyp Singleton Most Kompozyt Dekorator Fasada Pełnomocnik Pyłek Łańcuch zobowiązań Polecenie Iterator Mediator Pamiątka Obserwator Stan Strategie Odwiedzający
11
Sposób omawiania Nazwa Przeznaczenie Uzasadnienie stosowania
Co robi? Jakich zagadnień projektowych dotyczy? Uzasadnienie stosowania Problem projektowy wraz z rozwiązaniem Stosowalność Kiedy wybrać dany wzorzec projektowy? Struktura (uczestnicy, współpraca) Omówienie uczestników oraz ich współpracy przy pomocy diagramów Konsekwencje Co zyskujemy, a co tracimy wybierając dany wzorzec? Przykłady zastosowania
12
Dekorator Przeznaczenie
dynamicznie dołącza do obiektów dodatkowe zobowiązania zapewnia elastyczną alternatywę dla tworzenia podklas w celu rozszerzania funkcjonalności
13
Uzasadnienie stosowania
Dekorator Uzasadnienie stosowania Czasem chcemy dołączyć pewne zobowiązania do pojedynczego obiektu (nie do całej klasy) Pakiet narzędziowy do tworzenia interfejsów użytkownika powinien np. umożliwiać dodanie do każdego składnika takich elementów jak ramki, czy paski przewijania Rozwiązania: dziedziczenie ramki, dziedziczenie przewijania (statyczne) zagnieżdżenie obiektów – otoczka = dekorator
14
Dekorator Zagnieżdżenie to może być rekurencyjne:
15
Dekorator Aby to osiągnąć musimy zbudować strukturę klas:
16
Dekorator Stosowalność
aby dynamicznie i w przezroczysty sposób dodawać zobowiązania do pojedynczych obiektów w wypadku zobowiązań które mogą być cofnięte Gdy rozszerzanie przez definiowanie podklas jest niepraktyczne (dużo niezależnych rozszerzeń które przy próbie uwzględnienia każdej ich kombinacji prowadzą do ogromnej liczby podklas)
17
Dekorator Struktura
18
Dekorator Uczestnicy Komponent (KomponentWizualny)
Definiuje interfejs obiektów, do których można dynamicznie dołączać zobowiązania KomponentKonkretny (WidokTekstowy) Definiuje obiekt, do którego można dołączać zobowiązania Dekorator Zarządza odwołaniem do obiektu Komponent i definiuje interfejs dopasowany do interfejsu Komponentu DekoratorKonkretny (DekoratorZRamkami, DekoratorZSuwakiem) Dodaje zobowiązania do komponentu
19
Dekorator Współpraca Dekorator przesyła żądania do swojego obiektu Komponent Może wykonywać dodatkowe operacje przed lub po przesłaniu żądania
20
Dekorator Konsekwencje
większa elastyczność niż przy stosowaniu statycznego dziedziczenia (dodawanie, usuwanie dekoratorów, podwójna ramka) unikanie przeładowanych właściwościami klas na szczycie hierarchii „płać za to, czego potrzebujesz”, zamiast uwzględniać wszystkie przewidywane własności przy projektowanie klasy zasadniczej łatwiejsza rozszerzalność (dodanie dekoratora) Dekorator i jego komponent nie są identyczne (nie można polegać na sprawdzaniu identyczności obiektów) Projekt zawiera wiele małych obiektów różniących się nie zachowaniem, a sposobem połączenia może być trudne w zrozumieniu
21
Dekorator Przykłady Pakiety narzędziowe do tworzenie interfejsów użytkownika Strumienie Strumień *strumień = new StrumieńKompresujący( new ASCII7Strumień( new StrumieńPlikowy(„nazwaPliku”)));
22
Fasada Przeznaczenie zapewnia jednolity interfejs dla podsystemu o wielu interfejsach interfejs wyższego poziomu
23
Uzasadnienie stosowania
Fasada Uzasadnienie stosowania Typowym zadaniem projektowym jest sprowadzenie do minimum zależności i komunikacji między modułami Możemy to osiągnąć m.in. przez wprowadzenie fasady, która zapewnia interfejs bardziej ogólny zapewniający interfejs całego podsystemu
24
Fasada Mamy np. środowisko z podsystemem będącym kompilatorem. Mamy Parser, Analizator, WęzełProgramu, … Dla klienta, który pragnie jedynie skompilować kawałek programu, nie jest to istotne. Potrzebuje on interfejsu klasy Kompilator, będącego fasadą dla podsystemu
25
Fasada
26
Fasada Stosowalność zapewnienie prostego interfejsu do złożonego systemu stosowanie wzorców rozbija systemy na bardzo wiele małych klas, co powoduje się bardziej nadają się one do wielokrotnego użytku oraz są prostsze w rozbudowie rozrastanie się systemu powoduje natomiast, że klientowi trudniej jest go wykorzystać fasada zapewnia prosty, funkcjonalny interfejs, wystarczająco dobry dla większości klientów, który może pozostać stały nawet jeśli podsystem wewnątrz uległ zmianie zwiększa przenośność i niezależność podsystemu umożliwia układanie systemów warstwami (fasada definiuje punkty wejścia do podsystemu)
27
Fasada Struktura
28
Fasada Uczestnicy Fasada (Kompilator)
Wie jakie klasy podsystemu są odpowiedzialne, za spełnienie żądania Przekazuje żądania do odpowiednich obiektów systemu Klasa podsystemu (Parser, Analizator, …) Implementuje funkcjonalność systemu Wykonuje pracę przydzieloną przez fasadę Nie wie nic o fasadzie
29
Fasada Współpraca Klienci komunikują się z podsystemem, wysyłając żądania do Fasady, która przekazuje żądania do podsystemu (może być zmuszona przetłumaczyć swój interfejs na interfejsy podsystemu) Klienci korzystający z fasady nie muszą mieć bezpośredniego dostępu do obiektów jej podsystemu
30
Fasada Konsekwencje Mniejsza liczba obiektów, z którymi klient ma do czynienia (łatwość użycia) Mogą eliminować złożone lub cykliczne zależności między obiektami systemu Większa przenośność na inne platformy (przy jej użyciu jest mniejsze prawdopodobieństwo, że zmiana w jednym podsystemie spowoduje konieczność przebudowy pozostałych
31
Pełnomocnik Przeznaczenie
zapewnia reprezentanta innego obiektu w celu sterowania dostępem do obiektu oryginalnego
32
Uzasadnienie stosowania
Pełnomocnik Uzasadnienie stosowania Jednym z powodów sterowania dostępem do obiektu jest np. chęć odłożenia na później tworzenia/inicjowania tego obiektu np. wielkie obrazy rastowe w dokumencie Otwieranie dokumentu powinno być szybkie i dopiero kiedy obiekty stają się widoczne powinniśmy je budować… Powinno być to przezroczyste dla obiektu dokumentu Dlatego w miejsce rysunku tworzymy Pełnomocnika, który dopiero buduje obraz na żądanie wyświetlenia go
33
Pełnomocnik Pełnomocnik przechowując dodatkowo np. rozmiary obrazka może spełniać żądania programu formatującego bez potrzeby sięgania do egzemplarza rysunku Aby korzystać z tych udogodnień wystarczy do istniejącej struktury klas dodać pełnomocnika:
34
Pełnomocnik
35
Pełnomocnik Stosowalność
zawsze, gdy potrzeba uniwersalnego sposobu odwołania do obiektu (bardziej wyrafinowanego niż zwykły wskaźnik) np. Pełnomocnik zdalny lokalny reprezentant obiektu z innej przestrzeni adresowej Pełnomocnik wirtualny tworzy kosztowne obiekty na żądanie (np. PełnomocnikRysunku) Pełnomocnik ochraniający kontroluje dostęp do obiektu zapewnia różne prawa dla różnych obiektów
36
Pełnomocnik Sprytny wskaźnik
zastępuje zwykły wskaźnik, wykonując dodatkowe akcje przy dostępie do obiektu, jak: zliczanie liczby odwołań do obiektu (usuwanie przy braku odwołań) Ładowanie trwałych obiektów do pamięci przy pierwszym odwołaniu
37
Pełnomocnik Struktura
38
Pełnomocnik Uczestnicy Pełnomocnik (PełnomocnikRysunku)
Przechowuje odwołanie, umożliwiające mu dostęp do prawdziwego obiektu Zapewnia identyczny interfejs z oryginalnym obiektem (może wystąpić wszędzie tam, gdzie oryginał) Kontroluje dostęp do obiektu … (cokolwiek) Przedmiot (ObiektGraficzny) Definiuje wspólny interfejs dla PrawdziwegoPrzedmiotu i Pełnomocnika PrawdziwyPrzedmiot (Rysunek) Definiuje dowolny przedmiot
39
Pełnomocnik Współpraca
Pełnomocnik jeśli trzeba przekazuje żądania do PrawdziwegoPrzedmiotu (w zależności od rodzaju pełnomocnika)
40
Pełnomocnik Konsekwencje
dodatkowy poziom pośredniości dostępu do obiektu, może: ukryć fakt, że obiekt jest zdalny wykonywać optymalizacje jak tworzenie obiektu na żądanie dodatkowe czynności porządkowe ukrywanie np. kopiowania-przy-zapisywaniu odłożenie na później kopiowania obiektu – będzie on rzeczywiście skopiowany tylko jeśli użytkownika zażąda operacji modyfikującej kopię
41
Pyłek Przeznaczenie wykorzystuje współdzielenie obiektów, w celu efektywnej obsługi wielkiej liczby drobnych obiektów
42
Uzasadnienie stosowania
Pyłek Uzasadnienie stosowania Większość edytorów używa obiektów do przechowywania takich elementów jak tabele, rysunki Na ogół jednak powstrzymują się od stosowania obiektów do reprezentacji poszczególnych znaków w dokumencie, mimo że przyczyniłoby to się do zwiększenia elastyczności (nowe zestawy znaków, jednakowe traktowanie znaków i innych obiektów pod względem formatowania i wypisywania Przyczyną tego jest koszt pamięciowy takiego rozwiązania! Tutaj pojawia się Pyłek
43
Pyłek Jest on współdzielonym obiektem, który może być używany jednocześnie w wielu kontekstach Działa on jako obiekt niezależny w każdym kontekście (nie może niczego zakładać o kontekście działania) Jest nieodróżnialny od egzemplarza obiektu, który nie jest współdzielony Edytor może utworzyć Pyłek dla każdej litery alfabetu Każdy Pyłek przechowuje wtedy tylko kod znaku, jego miejsce i styl typograficzny natomiast są mu dostarczane przez algorytmy rozmieszczania i formatowania tekstu
44
Pyłek Logiczny punkt widzenia:
1 znak = 1 obiekt Fizycznie istnieje jednak jeden współdzielony obiekt dla każdej litery:
45
Pyłek Struktura klas takich obiektów wygląda tak:
Stan zewnętrzny musi być przekazywany jako parametr do niektórych operacji (dotyczących wystąpień znaków w dokumencie)
46
Pyłek Przechowywanie stanu zewnętrznego jest zadaniem Klienta, może być ono zaimplementowany w postaci BDrzewa: Węzły wewnętrzne = zakresy indeksów glifów Liście = style
47
Pyłek Stosowalność System używa wielkiej liczby obiektów
Koszty pamięciowe są wysokie ze względu na samą tylko liczbę obiektów Większość stanu obiektów może być przeniesiona na zewnątrz Po usunięciu stanu zewnętrznego wiele grup obiektów można zastąpić stosunkowo niewielką liczbą współdzielonych obiektów Tożsamość obiektów nie jest istotna w systemie
48
Pyłek Struktura
49
Pyłek Uczestnicy Pyłek (Glif) PyłekKonkretny (Znak) FabrykaPyłków
Deklaruje interfejs, przez który pyłki mogą otrzymywać stan zewnętrzny i działać zgodnie z nim PyłekKonkretny (Znak) Implementuje interfejs pyłku i dodaje pamięć do przechowywania stanu wewnętrznego Musi dawać się współdzielić (niezależność od kontekstu w jakim występuje) FabrykaPyłków Tworzy obiekty klasy Pyłek i zarządza nimi Zapewnia właściwe współdzielenie pyłków Klient Utrzymuje odwołania do pyłków Przechowuje stan zewnętrzny pyłków
50
Pyłek Współpraca Stan którego pyłek potrzebuje do działania musi być scharakteryzowany albo jako wewnętrzny albo zewnętrzny. Stan zewnętrzny jest dostarczany przez klienta Klienci nie powinni bezpośrednio tworzyć egzemplarzy klasy PyłekKonkretny (otrzymują je z FabrykiPyłków)
51
Pyłek Konsekwencje Zwiększenie czasu wykonywania w związku z przesyłaniem lub wyliczaniem stanu zewnętrznego Oszczędność pamięci Zmniejszenie łącznej liczby egzemplarzy (współdzielenie) Wielkość stanu wewnętrznego obiektu Wyliczanie/przechowywanie stanu zewnętrznego Często łączony z wzorcem Kompozyt w celu przedstawienia struktury hierarchicznej ze współdzielonymi węzłami/liśćmi (problem = stan wewnętrzny nie może zawierać wskaźnika do rodzica; rozwiązanie = rodzic przekazywany jako część stanu zewnętrznego)
52
Stan Przeznaczenie Umożliwia obiektowi zmianę zachowania, gdy zmienia się jego stan wewnętrzny Obiekt wydaje się zmieniać wówczas swoją klasę
53
Uzasadnienie stosowania
Stan Uzasadnienie stosowania Rozważmy klasę PołączenieTCP, reprezentującą połączenie sieciowe: Ilekroć połączenie zmienia stan, obiekt PołącznieTCP zmienia swój obiekt-stan => zmienia przez to swoje zachowanie
54
Stan Stosowalność Zachowanie obiektu zależy od jego stanu, a obiekt musi zmieniać swoje zachowanie w czasie wykonywania programu Operacje zawierają duże, skomplikowane instrukcje warunkowe, zależne od stanu obiektu Stan przenosi każde rozgałęzienie warunkowe do oddzielnej klasy
55
Stan Struktura
56
Stan Uczestnicy Kontekst (PołączenieTCP) Stan (StanTCP)
Definiuje interfejs dla Klientów Utrzymuje egzemplarz podklasy StanuKonkretnego, definiujący bieżący stan Stan (StanTCP) Definiuje interfejs do kapsułkowania zachowania związanego ze stanem Kontekstu Podklasa StanuKonkretnego (TCPNawiazane) Każda implementuje zachowanie związane ze stanem Kontekstu
57
Stan Współpraca Kontekst przekazuje żądania specyficzne dla stanu do obiektu StanKonkretny (być może przekazuje również siebie jako parametr) Klient konfiguruje Kontekst początkowym stanem, a następnie nie musi zajmować się bezpośrednio obiektami Stan O wyborze kolejnego stanu decyduje albo Kontekst, albo podklasy StanuKonkretnego
58
Stan Konsekwencje Całe zachowanie dotyczące stanu w jednym obiekcie
Dużo większa liczba klas Zachowanie mniej zwarte – korzystne gdy wiele stanów (inaczej duże instrukcje warunkowe) Jawność przejść między stanami (coś więcej niż tylko przypisanie kilku zmiennych) Atomowe przejścia między stanami (zmiana 1 zmiennej) Możliwość współdzielenia obiektów Stan
59
Stan Kto definiuje przejścia? (tego nie ustala wzorzec)
bardziej elastyczne wydaje się umożliwienie podklasom Stanu samodzielnego ustalenia ich następników wprowadza to niestety zależności implementacyjne (Stany muszą o sobie wiedzieć), co może prowadzić do problemów w dużych systemach z wieloma stanami
60
Stan Przykłady Wiele programów do rysowania zapewnia różnorodne „narzędzia”: narzędzie do rysowania narzędzie do zaznaczania W zależności od tego, które narzędzie jest aktywne operacje myszką wywołują inne efekty Można tu zastosować wzorzec Stanu do reprezentacji wybranego narzędzia
61
Stan
62
Bibliografia Gamma, Helm, Johnson, Vlissides „Wzorce projektowe”, WNT 2005.
Podobne prezentacje
© 2024 SlidePlayer.pl Inc.
All rights reserved.