Dokumentacja związana ze wzorcami projektowymi
DOKUMENTACJA INTERAKTYWNA
Spis treści
Dokumentacja związana ze wzorcami projektowymi – część 1.Dokumentacja związana ze wzorcami projektowymi – część 1.
Dokumentacja związana ze wzorcami projektowymi – część 2.Dokumentacja związana ze wzorcami projektowymi – część 2.
1. Dokumentacja związana ze wzorcami projektowymi – część 1
Dokumentacja związana ze wzorcami projektowymi.
Nagranie audio tożsame z treścią.
Dokumentacja wzorca projektowego zawiera kontekst, w jakim się go stosuje, informacje o rozwiązywanym problemie, a także sugerowane rozwiązanie. Układ opisu wzorca według Bandy Czterech zawiera następujące składowe: nazwę wzorca oraz klasyfikację, przeznaczenie, inne nazwy, motywację, stosowalność, strukturę, uczestników, współpracę, konsekwencje, implementację, przykładowy kod, przykłady zastosowania oraz pokrewne wzorce. W dokumentacji znajdują się przykłady wzorca kreacyjnego, strukturalnego, behawioralnego oraz architektonicznego. W poszczególnych sekcjach można przejrzeć zarówno przykład danego wzorca, jak i jego strukturę oraz przykładowy kod.
Wskazówki dotyczące wypełnienie dokumentu.
Nagranie audio tożsame z treścią.
Nazwa wzorca oraz klasyfikacja
Unikalna oraz opisowa nazwa, która pozwala na identyfikację oraz odwołanie się do wzorca.
Przeznaczenie
Powody, jakie stoją za wyborem wzorca, oraz opis jego celu.
Inne nazwy
Podaje się inne nazwy dla wzorca, jeżeli istnieją i są dobrze znane.
Motywacja
Scenariusz z problemem powiązanym z kontekstem, w którym wzorzec ma zastosowanie.
Stosowalność
Przypadki, w których użycie wzorca jest adekwatne.
Struktura
Prezentacja wzorca w formie graficznej, najczęściej jako diagram klas lub interakcji.
Uczestnicy
Lista klas i obiektów, które stosowane są we wzorcu, oraz ich zobowiązania.
Współpraca
Charakterystyka interakcji klas i obiektów, które wykorzystywane są we wzorcu.
Konsekwencje
Wykaz efektów ubocznych, wyników i kompromisów, jakie pojawiają się podczas wykorzystania wzorca.
Implementacja
Wskazówki i porady dotyczące implementacji wzorca, zwracające uwagę na specyficzne kwestie.
Przykładowy kod
Przykład z zastosowanym wzorcem wykorzystujący dany język programowania.
Przykłady zastosowania
Przykłady znanych zastosowań wzorca w istniejących programach.
Pokrewne wzorce
Inne wzorce, z którymi dany wzorzec się łączy poprzez wspólne stosowanie, a także wzorce, które mogą zastąpić dany wzorzec wraz z przedstawieniem różnic między nimi.
Struktura fabryki abstrakcyjnej
Widoczny jest schemat blokowy dotyczący zależności w strukturze fabryki abstrakcyjnej. Schemat zawiera trzy panele w części środkowej połączone z sześcioma z lewej i jednym z prawej strony. Centrum schematu wypełniają trzy panele z napisami od góry ConcreteFactory jeden poniżej Abstract Factory jeden+ create product A+ create product B na dole panel z napisem Concrete Factory dwa. Pierwszy i ostatni łączą się za pomocą strzałek z sześcioma panelami ułożonymi po trzy w dwóch rzędach. Napis na pierwszych dwóch Concrete A jeden B jeden poniżej napis Concrete produkt A Concrete produkt B poniżej Concrete produkt A dwa Concrete produkt B dwa. Po prawej stronie schematu widoczny jest panel z napisem Client -factory :AbstractFactory+Client(f:AbstractFactory+someOperation() będący w zależności z panelem Abstract Factory. Poniżej widoczny jest kod
Objaśnienie pierwsze. Przykład Fabryki Abstrakcyjnej na podstawie prostego programu do tworzenia GUI na różnych systemach operacyjnych, Python
Wers pierwszy przykładowy kod
objaśnienie drugie. Import niezbędnych bibliotek
nowy wers from abc import ABC przecinek abstractmethod
Objaśnienie trzecie. Tworzenie klasy Fabryki abstrakcyjnej
nowy wers klas GUIFactory otwórz nawias okrągły a be ce zamknij nawias okrągły dwukropek
nowy wers def createtButton otwórz nawias okrągły self zamknij nawias okrągły minus zamknij nawias ostrokątny checkbox dwukropek
nowy wers pass
Objaśnienie czwarte. Implementacja konkretnych fabryk
nowy wers klas winfactory otwórz nawias okrągły GUIFactory zamknij nawias okrągły dwukropek
nowy wers def createWinButton otwórz nawias okrągły self zamknij nawias okrągły minus zamknij nawias ostrokątny button dwukropek
nowy wers return WinButton otwórz nawias okrągły zamknij nawias okrągły
nowy wers def createcheckbox otwórz nawias okrągły self zamknij nawias okrągły minus zamknij nawias ostrokątny checkbox dwukropek
nowy wers return Wincheckbox otwórz nawias okrągły zamknij nawias okrągły
nowy wers Class macfactory otwórz nawias okrągły guiFactory zamknij nawias okrągły dwukropek
nowy wers Def createmacButton otwórz nawias okrągły self zamknij nawias okrągły minus zamknij nawias ostrokątny button dwukropek
nowy wers Return macbutton otwórz nawias okrągły zamknij nawias okrągły
nowy wers Def createcheckbox otwórz nawias okrągły self zamknij nawias otwarty minus zamknij nawias ostrokątny checkbox dwukropek
nowy wers Return maccheckbox otwórz nawias okrągły zamknij nawias okrągły
Objaśnienie piąte. Implementacja produktów
nowy wers Class button otwórz nawias okrągły a be ce zamknij nawias okrągły dwukropek
nowy wers Def paint otwórz nawias okrągły self zamknij nawias okrągły minus zamknij nawias ostrokątny es te er dwukropek
nowy wers Pass
Objaśnienie szóste. Konkretne fabryki mają swoje konkretne produkty
nowy wers Class winbutton otwórz nawias okrągły a be ce zamknij nawias okrągły dwukropek
nowy wers Def paint otwórz nawias okrągły self zamknij nawias okrągły minus zamknij nawias ostrokątny es te er dwukropek
nowy wers Return otwórz cudzysłów windows button zamknij cudzysłów
nowy wers Class macbutton otwórz nawias okrągły a be ce zamknij nawias okrągły dwukropek
nowy wers Def paint otwórz nawias okrągły self zamknij nawias okrągły minus zamknij nawias ostrokątny es te er dwukropek
nowy wers Return otwórz cudzysłów macos button zamknij cudzysłów
Objaśnienie siódme. Tutaj drugi przykładowy produkt
nowy wers Class checkbox otwórz nawias okrągły a be ce zamknij nawias okrągły dwukropek
nowy wers Def paint otwórz nawias okrągły self zamknij nawias okrągły minus zamknij nawias ostrokątny es te er dwukropek
nowy wers Pass
nowy wers Class wincheckbox otwórz nawias okrągły a be ce zamknij nawias okrągły dwukropek
nowy wers Def paint otwórz nawias okrągły self zamknij nawias okrągły minus zamknij nawias ostrokątny es te er dwukropek
nowy wers Return otwórz cudzysłów windows checkbox zamknij cudzysłów
nowy wers class maccheckbox otwórz nawias okrągły a be ce zamknij nawias okrągły dwukropek
nowy wers Def paint otwórz nawias okrągły self zamknij nawias okrągły minus zamknij nawias ostrokątny es te er dwukropek
nowy wers Return otwórz cudzysłów macos checkbox zamknij cudzysłów
Objaśnienie ósme. Klient wykorzystuje jedynie fabryki i produkty abstrakcyjne. Pozwala to przekazywać klientowi dowolną podklasę produktu lub fabryki
nowy wers class application otwórz nawias okrągły guifactory przecinek button zamknij nawias okrągły dwukropek
nowy wers Def podkreślnik dolny init podkreślnik dolny otwórz nawias okrągły self przecinek factory znak równości guifactory zamknij nawias okrągły dwukropek
nowy wers Self kropka factory znak równości factory
nowy wers Def createui otwórz nawias okrągły self zamknij nawias okrągły dwukropek
nowy wers Self kropka button znak równości factory kropka createbutton otwórz i zamknij nawias okrągły
nowy wers Def paint otwórz nawias okrągły self zamknij nawias okrągły dwukropek
nowy wers self kropka button kropka paint otwórz i zamknij nawias okrągły
Objaśnienie dziewiąte. Aplikacja rozpoznaje system operacyjny i wybiera odpowiednią fabrykę
nowy wers Class aplicationconfigurator otwórz i zamknij nawias okrągły dwukropek
nowy wers Def main otwórz i zamknij nawias okrągły dwukropek
nowy wers Config znak równości readapplicationconfnigfile otwórz i zamknij nawias okrągły
nowy wers If otwórz nawias okrągły config kropka o es znak równości znak równości otwórz cudzysłów windows zamknij cudzysłów zamknij nawias okrągły dwukropek
nowy wers Factory znak równości winfactory otwórz i zamknij nawias okrągły
nowy wers Elif otwórz nawias okrągły config kropka o es znak równości znak równości. Otwórz cudzysłów mac zamknij cudzysłów zamknij nawias okrągły dwukropek
nowy wers Factory znak równości macfactory otwórz i zamknij nawias okrągły
nowy wers Else dwukropek
nowy wers Throw exception otwórz nawias okrągły otwórz cudzysłów error wykrzyknik unknown operating system kropka zamknij cudzysłów zamknij nawias okrągły
nowy wers app znak równości application otwórz nawias okrągły factory zamknij nawias okrągły
Wzorzec kreacyjny jeden myślnik struktura i kod.
Opis wzorca myślnik ćwiczenie pierwsze. Nagranie jest tożsame z treścią.
Fabryka abstrakcyjna to wzorzec kreacyjny. Dostarcza interfejs do tworzenia różnych obiektów tego samego typu bez konieczności specyfikowania ich konkretnych klas. Motywacją Abstract Factory jest stworzenie programu, który umożliwia tworzenie obiektów należących do tej samej rodziny (A, B, C), które dodatkowo mogą posiadać jedną z cech (1, 2, 3) – w jednym momencie tworzymy zatem 3 obiekty: A, B i C o takiej samej cesze: 1, 2 lub 3. Ważne jest, żeby program dawał możliwość łatwego dodania cechy lub zmiany rodziny zależnie od potrzeb klienta bez konieczności znacznego zmieniania lub mnożenia kodu. Fabryka abstrakcyjna to wzorzec kreacyjny.
Opis wzorca myślnik ćwiczenie drugie. Nagranie jest tożsame z treścią.
Fabryka abstrakcyjna stosowana jest dla grup obiektów, które w momencie ich tworzenia powinny posiadać tę samą cechę, ale wybrana może zostać jedna z kilku dostępnych cech, np. zamówione przez klienta meble powinny składać się z elementów pochodzących z jednej kolekcji, ale klient ma możliwość wyboru stylu mebli. Osoba prowadząca sklep meblarski, korzystająca z fabryki abstrakcyjnej, nie powinna mieć potrzeby znajomości klasy, która jest wykorzystywana do wytworzenia obiektów z danej rodziny – jej rolą jest jedynie możliwość nadania cech danej rodzinie obiektów poprzez stworzenie odpowiedniej klasy z użyciem interfejsu fabryki abstrakcyjnej. Uczestnicy; Fabryka abstrakcyjna – interfejs zawierający w sobie metody tworzenia obiektów z danej rodziny. Klasa fabryczna – klasa, która korzysta z interfejsu fabryki abstrakcyjnej oraz jej metod, dodająca do wytwarzanych obiektów dodatkowe cechy. Fabryka abstrakcyjna dostarcza zestaw metod, które umożliwiają tworzenie szerokiej gamy obiektów, które dzielą wiele właściwości, niezależnie od cech nadawanych później przez klasy fabryczne, np. meble kuchenne, niezależnie od stylu, będą posiadały drzwi, szuflady, półki, blaty, z kolei klasa fabryczna daje możliwość nadawania poszczególnym rodzinom obiektów dodatkowych cech i właściwości – pozwala to używać wielokrotnie kodu obecnego w fabryce abstrakcyjnej, a jednocześnie zwiększa czytelność i elastyczność kodu poprzez stosowanie klas fabrycznych.
Opis wzorca myślnik ćwiczenie trzecie. Nagranie jest tożsame z treścią.
Zaletą produktów tworzonych przy użyciu fabryki są ze sobą kompatybilne, kod kreacyjny można umieścić w jednym miejscu programu, co ułatwia utrzymanie kodu. Można w prosty sposób rozszerzać funkcjonalność fabryki abstrakcyjnej, np. poprzez dodawanie nowych produktów bez ingerencji w kod kliencki. Niestety może dochodzić do nadmiernego skomplikowania kodu, z uwagi na konieczność utworzenia wielu klas i interfejsów. W pierwszej kolejności tworzy się interfejsy produktów: analizuje się cechy wspólne, jakie powinny mieć produkty tworzone później w klasach fabrycznych. Następnie tworzy się fabrykę abstrakcyjną, która zepnie w sobie interfejsy ({metody}) tworzenia poszczególnych produktów z danej rodziny (każda rodzina produktów wymaga własnej fabryki abstrakcyjnej). Kolejnym etapem jest stworzenie klasy fabrycznej odnoszącej się do fabryki abstrakcyjnej. Na końcu umieszczamy w kodzie komendę inicjalizującą utworzenie obiektu fabrycznego, dającego możliwość wytwarzania produktów.
Opis wzorca myślnik ćwiczenie czwarte. Nagranie jest tożsame z treścią.
Fabrykę abstrakcyjną stosuje się do generowania GUI na różnych systemach operacyjnych, gdzie dla każdego systemu operacyjnego za generowanie GUI będzie odpowiadać inna klasa fabryczna, a cechy wspólne interfejsów są zakodowane w fabryce abstrakcyjnej. Fabryka abstrakcyjna wywodzi się z metody wytwórczej, która jest prostszym wzorcem projektowym, mogącym mieć podobne zastosowanie. Wzorzec budowniczy, podobnie jak fabryka abstrakcyjna, wykorzystywany jest do tworzenia obiektów, jednak fabryka abstrakcyjna specjalizuje się w tworzeniu rodzin spokrewnionych ze sobą obiektów, a wzorzec budowniczy koncentruje się na konstruowaniu złożonych obiektów krok po kroku; fabryka abstrakcyjna zwraca produkt natychmiast po jej wywołaniu, natomiast wzorzec budowniczy pozwala dodawać kolejne etapy konstrukcji w celu modyfikacji produktu przed jego pobraniem. Fabryka abstrakcyjna może współdziałać z mostem, zwłaszcza gdy {most} może działać wyłącznie z wybranymi implementacjami – fabryka abstrakcyjna pozwala zhermetyzować te relacje i ukryć zawiłości przed kodem klienckim.
Struktura fasady
Widoczny jest schemat blokowy dotyczący zależności w strukturze fasady. Od lewej znajduje się panel z napisem Client strzałka kieruje do panelu z napisem Facade linksToSubsystemObjects -option AdditionalFacade kolejna strzałka kieruje do panelu Additional Facade + another Operation Od obu paneli strzałki kierują w dół do licznych paneli z napisem Subsystem class. Poniżej widoczny jest kod
wers pierwszy: Przykładowy kod
Objaśnienie 1: Przykład Fasady na podstawie prostego programu do konwersji filmów, Python
Objaśnienie 2: Początkowo widzimy klasy złożonego frameworku, dla których chcemy stworzyć Fasadę
Nowy wers classVideoFile okrągły nawias koniec nawiasu dwukropek
Nowy wers Prawy Ukośnik prawy ukośnik trzykropek
Nowy wers classOggCompressionCodec nawias okrągły koniec nawiasu dwukropek
Nowy wers Prawy Ukośnik prawy ukośnik trzykropek
Nowy wers classMPEG4CompressionCodec nawias okrągły koniec nawiasu dwukropek
Nowy wers Prawy Ukośnik prawy ukośnik trzykropek
Nowy wers class CodecFactorynawias okrągły koniec nawiasu dwukropek
Nowy wers Prawy ukośnik prawy ukośnik trzykropek
Nowy wers Class BitrateReader nawias okrągły koniec nawiasu dwukropek
Nowy wers Prawy ukośnik prawy ukośnik trzykropek
Nowy wers class AudioMixer nawias okrągły koniec nawiasu dwukropek
Nowy wers Prawy ukośnik prawy ukośnik trzykropek
Objaśnienie 3: Tutaj zaczynamy tworzyć fasadę
Nowy wers Class VideoConverter nawias okrągły VideoFile przecinek OggCompressionCodec przecinek MPEG4CompressionCodec przecinek CodecFactory przecinek BitrateReader przecinek AudioMixer koniec nawiasu dwukropek
Nowy wers Def podkreślnik init podkreślnik otwórz nawias okrągły self przecinek videofile znak równości VideoFile przecinek oggcp znak równości OggCompressionCodec przecinek mp4cpznak równości MPEG4CompressionCodec przecinek codec podkreślnik factory znakrówności CodecFactory przecinek bitrate podkreślnik reader znak równości BitrateReader przecinek audio podkreślnik mixer znak równości AudioMixer zamknij nawias dwukropek
Nowy wers Selfkropkavideofile znakrówności Videofile otwórz nawias okrągły koniec nawiasu
Nowy wers self kropka oggcp znak równości oggcp otwórz nawias okrągły koniec nawiasu
Nowy wers self kropka mp4cp znak równości mp4cp otwórz nawias okrągły koniec nawiasu
Nowy wers self kropka codec podkreślnik factory znak równości podkreślnik factory otwórz nawias okrągły koniec nawiasu
Nowy wers self kropka bitrate podkreślnik reader znak równości bitrate podkreślnik reader otwórz nawias okrągły koniec nawiasu
Nowy wers self kropka audio podkreślnik mixer znak równości audio podkreślnik mixer otwórz nawias okrągły koniec nawiasu
Nowy wers def convert otwórz nawias okrągły filename przecinek format koniec nawiasu dwukropek
Nowy wers file znak równości videofile otwórz nawias okrągły filename koniec nawiasu
Nowy wers sourceCodec znak równości codec podkreślnik factory kropka extract otwórz nawias okrągły file zamknij nawias okrągły
Nowy wers if otwórz nawias okrągły format znak równości znak równości cudzysłów mp4 cudzysłów zamknij nawias okrągły dwukropek
Nowy wers destinationCodec znak równości mp4cp otwórz nawias okrągły koniec nawiasu
Nowy wers Else dwukropek
Nowy wers destinationCodec znak równości oggcp otwórz nawias okrągły koniec nawiasu
Nowy wers buffer znak równości podkreślnik reader kropka read otwórz nawias okrągły filename przecinek sourceCodec koniec nawiasu
Nowy wers result znak równości bitrade podkreślnik reader kropka convert otwórz nawias okrągły buffer przecinek destinationCodec koniec nawiasu
Nowy wers result znak równości audio podkreślnik mixer kropka fix otwórz nawias okrągły result koniec nawiasu
Nowy wers return result
Objaśnienie 4: Teraz tworzymy aplikację korzystającą z Fasady
Nowy wers Class Application otwórz nawias okrągły koniec nawiasu dwukropek
Nowy wers Def main otwórz nawias okrągły koniec nawiasu dwukropek
Nowy wers Converter znak równości VideoConverter otwórz nawias okrągły koniec nawiasu
Nowy wers mp4 znak równości converter kropka convert otwórz nawias okrągły cudzysłów funny myślnik cats myślnik video kropka ogg cudzysów przecinek cudzysłów mp4 cudzysłów koniec nawiasu
Nowy wers mp4 kropka save otwórz nawias okrągły koniec nawiasu
Wzorzec strukturalny jeden myślnik struktura i kod. Opis wzorca:
Opis wzorca myślnik ćwiczenie pierwsze. Nagranie jest tożsame z treścią.
Fasada ,to przykłada wzorca projektowego, którego przeznaczeniem jest wyposażenie biblioteki, frameworku lub innego złożonego zestawu klas w uproszczony interfejs .Fasada wykorzystywana jest w sytuacji, gdy nasz kod musi wykorzystywać pewne elementy bardzo dużej i skomplikowanej biblioteki lub frameworku, których implementacja i późniejsza modyfikacja wymaga dokładnego śledzenia zależności, co wymaga poświęcenia dużej ilości czasu i zwiększa szanse zaistnienia błędu. Stworzenie uproszczonego interfejsu wyodrębniającego stosowane przez nas funkcje znacząco upraszcza ich stosowanie i ułatwia utrzymanie kodu kosztem ograniczenia liczby funkcji biblioteki, które możemy zastosować.
Opis wzorca myślnik ćwiczenie drugie. Nagranie jest tożsame z treścią.
Fasadę można wykorzystać wszędzie tam, gdzie wykorzystuje się kod pochodzący z zewnętrznego źródła o bardzo dużym poziomie skomplikowania i wewnętrznych zależności (biblioteki, frameworki), a jednocześnie wymagany jest tylko wąski zakres funkcjonalności dostarczanych przez dane źródło kodu. Tworząc Fasadę, czyli uproszczony interfejs pozwalający wykorzystywać wybrane funkcje danej biblioteki, znacząco upraszczamy sposób ich używania, co zwiększa czytelność i zrozumienie kodu, a tym samym ułatwia jego utrzymanie. Uczestnicy: Fasada – pełni rolę interfejsu pośredniczącego między klientem, a jakimś złożonym podsystemem, ułatwia stosowanie pewnych funkcji wchodzących w skład tego podsystemu.Złożony podsystem – może być nim biblioteka, framework lub inna złożona grupa klas, która zawiera w sobie szereg funkcji, które mogą być wspólnie wykorzystywane.
Złożony podsystem jest źródłem klas, obiektów i funkcji, które mogą być używane przez klienta do przeprowadzania określonych operacji. Klasa Fasady zamyka w sobie najważniejsze funkcje biblioteki i dodatkowo może je ze sobą łączyć w pojedynczych metodach, dając klientowi narzędzie do łatwego ich wykorzystywania. Fasada pełni funkcję pośrednika między klientem, a biblioteką, dając mu łatwy dostęp do ograniczonej liczby funkcjonalności biblioteki. W przypadku potrzeby zastosowania większej ilości funkcji oferowanych przez bibliotekę, warto jest stworzyć więcej niż jedną Fasadę, aby nie doprowadzić do stanu, w którym pojedyncza Fasada będzie posiadać zależności do większości lub wszystkich klas w aplikacji.
Opis wzorca myślnik ćwiczenie trzecie. Nagranie jest tożsame z treścią.
Fasada w znaczący sposób ułatwia stosowanie ograniczonej liczby funkcji danego podsystemu, co zwiększa czytelność i łatwość utrzymania kodu. Pozwala odizolować kod kliencki od złożoności podsystemu. Wady: Fasada może stać się „boskim obiektem” posiadającym powiązania z każdą klasą w strukturze aplikacji.
Fasadę można zastosować w dwóch przypadkach: gdy chcemy wyodrębnić część funkcjonalności oferowanych przez framework lub bibliotekę i stworzyć dla nich prosty w użyciu interfejs lub gdy chcemy podzielić dany podsystem na warstwy. W obu przypadkach, w pierwszej kolejności upewnij się, że stworzony interfejs będzie prostszy od aktualnego interfejsu podsystemu. Jeśli tak, to stwórz klasę Fasady. Dobrze jest, gdy Fasada jest jedyną drogą wyjścia kodu klienckiego do danego podsystemu – w razie zmian w kodzie podsystemu, niezbędne będzie jedynie wprowadzenie zmian w kodzie Fasady, bez potrzeby zmieniania wielu linii kodu klienckiego. Wewnątrz Fasady implementuje się odpowiednie metody i funkcje, odpowiedzialne za inicjalizację i zarządzanie cyklem życia podsystemu, jak również przekierowywanie wywołań z kodu klienckiego do obiektów podsystemu. Gdy Fasada stanie się zbyt duża, wydziela część funkcji do nowej Fasady.
Opis wzorca myślnik ćwiczenie czwarte. Nagranie jest tożsame z treścią.
Przykładem zastosowania tego wzorca projektowego może być kod aplikacji bankomatowej, który stanowi Fasadę dla klienta, udostępniającą mu niezbędne funkcje, takie jak autoryzacja karty, sprawdzenie stanu konta, wpłata czy {wypłata} gotówki. Izoluje ona również klienta od skomplikowanej struktury systemu bankowego, która zawiera w sobie wiele dodatkowych {funkcji} zbędnych dla klienta. Fasada pełni bardzo podobne funkcje do Mediatora, z tą różnicą, że w przypadku Fasady utworzony zostaje uproszczony interfejs podsystemu, a komunikujące się ze sobą podsystemy nie wiedzą o istnieniu {Fasady}. W przypadku Mediatora dochodzi do centralizacji komunikacji, która przebiega przez Mediatora, a poszczególne podsystemy wiedzą jedynie o istnieniu Mediatora, nie mają możliwości bezpośredniej komunikacji z innymi podsystemami. Fasada i Adapter wpływają na interfejs podsystemu, jednak w przypadku Fasady utworzony zostaje nowy interfejs i obejmuje on grupę obiektów, z kolei Adapter stosuje się dla pojedynczego obiektu i zwiększa zastosowalność jego aktualnego interfejsu. Jeśli jedyną rolą Fasady byłoby ukrycie przed kodem klienckim procesu tworzenia obiektów podsystemu, może ona zostać zastąpiona przez Fabrykę Abstrakcyjną.
Struktura kompozytu
Widoczny jest schemat blokowy dotyczący zależności w strukturze kompozytu. Schemat zawiera trzy panele od lewej strony i jeden z prawej. Od góry widoczny napis Client poniżej Component + execute ().Od niego zależny jest panel niższy z napisem Leaf + execute() . Po prawej stronie widnieje panel z napisem Composite – children:Component[] + add ( c: Component)+remove(c:Component[]+getChildren():Component []+execute().Pozostaje on w zależności do panelu Component, który znajduje się z lewej strony.
Przykładowy kod
Objaśnienie 1: Komponent na przykładzie prostego programu graficznego, Python
Objaśnienie 2: Import niezbędnych bibliotek
Nowy wers from abc import ABC abstractmethod
Nowy wers from typing import List
Objaśnienie 3: Interfejs komponentu definiuje zachowanie zarówno dla prostych, jak i złożonych elementów kompozytu
Nowy wers class Graphic otwarcie nawiasu okrągłego ABC zamknięcie nawiasu okrągłego
Nowy wers małpa property
Nowy wers def parent otwarcie nawiasu okrągłego self zamknięcie nawiasu okrągłego minus zamknięcie nawiasu ostrego Graphic dwukropek
Nowy wers return self kropka parent
Nowy wers małpa parent kropka setter
Nowy wers def parent otwarcie nawiasu okrągłego self przecinek parent dwukropek Graphic zamknięcie nawiasu okrągłego dwukropek
Nowy wers self kropka parent równa się parent
Nowy wers def move otwarcie nawiasu okrągłego x przecinek y zamknięcie nawiasu okrągłego dwukropek
Nowy wers pass
Objaśnienie 4: Definiujemy klasę dla prostego obiektu, wykonującego konkretne operacje.
Nowy wers def draw otwarcie nawiasu okrągłego zamknięcie nawiasu okrągłego dwukropek
Nowy wers pass
Nowy wers class Dot otwarcie nawiasu okrągłego Graphic przecinek x przecinek y zamknięcie nawiasu okrągłego dwukropek
Nowy wers def podkreślnik init podkreślnik otwarcie nawiasu okrągłego self przecinek x przecinek y zamknięcie nawiasu okrągłego dwukropek
Nowy wers self kropka x równa się x
Nowy wers self kropka y równa się y
Nowy wers def move otwarcie nawiasu okrągłego x przecinek y zamknięcie nawiasu okrągłego dwukropek
Nowy wers self kropka x plus równa się x przecinek self kropka y plus równa się y
Nowy wers def draw otwarcie nawiasu okrągłego x przecinek y zamknięcie nawiasu okrągłego dwukropek
Nowy wers return f otwarcie cudzysłowu Narysowano punkt o współrzędnych otwarcie nawiasu klamrowego x zamknięcie nawiasu klamrowego i otwarcie nawiasu klamrowego y zamknięcie nawiasu klamrowego zamknięcie cudzysłowu
Objaśnienie 5: Wszystkie klasy komponentów mogą rozszerzać inne komponenty
Nowy wers class Circle otwarcie nawiasu okrągłego Dot przecinek radius zamknięcie nawiasu okrągłego dwukropek
Nowy wers def podkreślnik init podkreślnik otwarcie nawiasu okrągłego self przecinek x przecinek y przecinek radius zamknięcie nawiasu okrągłego dwukropek
Nowy wers self kropka x równa się x
Nowy wers self kropka y równa się y
Nowy wers self kropka radius równa się radius
Nowy wers def draw otwarcie nawiasu okrągłego zamknięcie nawiasu okrągłego
Nowy wers return f cudzysłów Narysowano okrąg o współrzędnych otwarcie nawiasu klamrowego x zamknięcie nawiasu klamrowego i otwarcie nawiasu klamrowego y zamknięcie nawiasu klamrowego i promieniu otwarcie nawiasu klamrowego radius zamknięcie nawiasu klamrowego cudzysłów
Objaśnienie 6: Klasa kompozyt reprezentuje komponenty złożone, które mogą posiadać potomstwo. Obiekty kompozytowe zazwyczaj delegują faktyczną pracę swoim dzieciom.
Nowy wers class CompoundGraphic otwarcie nawiasu okrągłego Graphic zamknięcie nawiasu okrągłego dwukropek
Nowy wers def podkreślnik init podkreślnik otwarcie nawiasu okrągłego self zamknięcie nawiasu okrągłego minus zamknięcie nawiasu ostrokątnego None dwukropek
Nowy wers self kropka children dwukropek List otwarcie nawiasu kwadratowego Graphic zamknięcie nawiasu kwadratowego równa się otwarcie nawiasu kwadratowego zamknięcie nawiasu kwadratowego
Objaśnienie 7: Kompozyt może dodawać lub usuwać komponenty (zarówno proste, jak i złożone) do\ze swej listy obiektów‑dzieci
Nowy wers def add otwarcie nawiasu okrągłego self przecinek child dwukropek Grapfic zamknięcie nawiasu okrągłego dwukropek
Nowy wers self kropka children kropka append otwarcie nawiasu okrągłego child zamknięcie nawiasu okrągłego
Nowy wers child kropka parent równa się self
Nowy wers def remove otwarcie nawiasu okrągłego self przecinek child kropka Graphic zamknięcie nawiasu okrągłego
Nowy wers self kropka children kropka remove otwarcie nawiasu okrągłego child zamknięcie nawiasu okrągłego
Nowy wers child kropka parent równa się self
Nowy wers def remove otwarcie nawiasu okrągłego self przecinek child dwukropek Graphic zamknięcie nawiasu okrągłego dwukropek
Nowy wers self kropka children kropka remove otwarcie nawiasu okrągłego child zamknięcie nawiasu okrągłego
Nowy wers child kropka parent równa się None
Nowy wers def move otwarcie nawiasu okrągłego x przecinek y zamknięcie nawiasu okrągłego dwukropek
Nowy wers for child in children dwukropek
Nowy wers child kropka move otwarcie nawiasu okrągłego x przecinek y zamknięcie nawiasu okrągłego
Nowy wers def draw otwarcie nawiasu okrągłego zamknięcie nawiasu okrągłego dwukropek
Nowy wers for child in children dwukropek
Nowy wers child kropka draw otwarcie nawiasu okrągłego zamknięcie nawiasu okrągłego
Objaśnienie 8: Kod klienta komunikuje się ze wszystkimi komponentami dzięki interfejsowi bazowemu, dzięki czemu posiada on wsparcie zarówno dla prostych, jak i złożonych obiektów Kompozytu.
Nowy wers class ImageEditorotwarcie nawiasu okrągłego CompoundGraphic zamknięcie nawiasu okrągłego
Nowy wers def load otwarcie nawiasu okrągłego zamknięcie nawiasu okrągłego dwukropek
Nowy wers all równa się CompoundGraphic otwarcie nawiasu okrągłego zamknięcie nawiasu okrągłego
Nowy wers all kropka add otwarcie nawiasu okrągłego Dot otwarcie drugiego nawiasu okrągłego liczba jeden przecinek liczba 2 zamknięcie podwójnym nawiasem okrągłym
Nowy wers all kropka add otwarcie nawiasu okrągłego Circle otwarcie drugiego nawiasu okrągłego liczba pięć przecinek liczba trzy przecinek liczba dziesięć zamknięcie podwójnym nawiasem okrągłym
Objaśnienie 9: Metoda łącząca wybrane obiekty w Kompozyt i rysująca obiekt
Nowy wers def groupSelected otwarcie nawiasu okrągłego components dwukropek Graphic kropka children zamknięcie nawiasu okrągłego dwukropek
Nowy wers group równa się CompoundGraphic otwarcie nawiasu okrągłego zamknięcie nawiasu okrągłego
Nowy wers for component in components dwukropek
Nowy wers group kropka add otwarcie nawiasu okrągłego component zamknięcie nawiasu okrągłego
Nowy wers all kropka remove otwarcie nawiasu okrągłego component zamknięcie nawiasu okrągłego
Nowy wers all kropka add otwarcie nawiasu okrągłego group zamknięcie nawiasu okrągłego
Nowy wers all kropka draw otwarcie nawiasu okrągłego zamknięcie nawiasu okrągłego
Opis strukturalny dwa myślnik struktura i kod. Opis wzorca:
Opis wzorca myślnik ćwiczenie pierwsze. Nagranie jest tożsame z treścią.
Kompozyt to kolejny przykład wzorca strukturalnego. Umożliwia komponowanie poszczególnych obiektów w struktury drzewiaste, a następnie traktowanie ich jak osobne obiekty. Inna nazwa dla tego wzorca to Drzewo obiektów, (ang. Object Tree Composite).Ten wzorzec projektowy znajduje zastosowanie w momencie, gdy można przedstawić daną strukturę obiektów w postaci drzewa. Pozwala on rozwiązać problem operowania na obiektach, które są zagnieżdżone wewnątrz drzewiastej struktury (stanowią jedną z gałęzi, która potem może, ale nie musi, rozgałęziać się po raz kolejny) i do których nie ma bezpośredniego dostępu, a jednocześnie niekoniecznie znamy typ czy też klasę danego obiektu. Przykładem może być zliczanie wszystkich pojedynczych elementów należących do danej struktury lub próba wykonania innej operacji na każdym pojedynczym elemencie.
Opis wzorca myślnik ćwiczenie drugie. Nagranie jest tożsame z treścią.
W przypadku zastosowania Kompozytu wykorzystujemy metodę bądź funkcję, która może zostać wykonana na każdym elemencie drzewa, a otrzymywana odpowiedź zależy od rodzaju i zawartości danego obiektu (czyli czy mamy do czynienia z końcową gałęzią, czy też z taką, która posiada dalsze rozgałęzienia). W przypadku dotarcia do obiektu nie posiadającego w sobie następnych obiektów, zwracana jest oczekiwana wartość, np. cena, rozmiar czy wartość innego atrybutu, a dla obiektu zawierającego w sobie kolejne elementy (np. dla listy) ta sama funkcja jest wykonywana na każdym elemencie wewnątrz tego obiektu. Dzięki temu wykonując jedną operację i wykorzystując rekurencję możemy przeanalizować wszystkie obiekty wchodzące w skład struktur o dużej złożoności pod kątem interesujących nas parametrów. Uczestnicy: Interfejs Komponentu – umożliwia operowanie na strukturze drzewiastej, zarówno na jej prostych, jak i złożonych komponentach. Obiekt złożony – struktura zawierająca w sobie prostsze obiekty, dla każdego obiektu złożonego wykorzystywane jest zjawisko rekurencji, czyli ta sama funkcja jest wykonywana na wszystkich elementach wchodzących w skład tego obiektu. Obiekt prosty – struktura niebędąca kontenerem dla kolejnych obiektów, wywoływana na niej funkcja czy metoda zwraca wartość, która jest oczekiwana przez klienta. Interfejs komponentu opisuje, w jaki sposób dana funkcja ma operować na obiektach złożonych oraz prostych. W przypadku obiektów złożonych, interfejs z reguły implementuje wykonywanie tej samej funkcji na każdym elemencie wewnątrz obiektu złożonego. Operacja ta pozwala niejako rozpakować wszystkie złożone obiekty i dotrzeć do wszystkich prostych obiektów wchodzących w skład komponentu, dla których ta sama funkcja wykonuje konkretną operację i/lub zwraca oczekiwaną wartość.
Opis wzorca myślnik ćwiczenie trzecie. Nagranie jest tożsame z treścią.
Kompozyt w znaczący sposób ułatwia pracę ze złożonymi obiektami o strukturze drzewiastej, dzięki wykorzystaniu rekurencji. Można łatwo dodawać nowe obiekty do struktury drzewiastej bez obaw zaburzenia pracy kodu w innych elementach struktury – kod w komponencie jest modułowy, a co za tym idzie, nie wpływa na działanie innych komponentów, które nie są powiązane z konkretnym modułem. W przypadku struktury zawierającej obiekty o bardzo zróżnicowanych funkcjonalnościach stworzenie uniwersalnego interfejsu może być bardzo utrudnione i wymagać stworzenia interfejsu bardzo ogólnego, który będzie trudny do zrozumienia. Najważniejszą rzeczą dla stworzenia komponentu jest upewnienie się, że daną strukturę można przedstawić w postaci drzewa, a poszczególne elementy drzewa mogą być zarówno typami prostymi, jak i złożonymi. Następnym krokiem będzie stworzenie interfejsu opisującego, jak funkcja ma postępować z elementami prostymi, a jak ze złożonymi. Należy także stworzyć odpowiednie klasy: jedne będą opisywać typy proste, inne zaś typy złożone komponenty. W klasach elementów prostych opisujemy, jakie metody mogą być wykonywane na obiektach tych klas i jakie wartości będą zwracane. Z kolei dla klas elementów złożonych definiujemy, jakie obiekty mogą być ich zawartością oraz interfejs, jaki będzie wykorzystywany do operowania na instancjach tych klas, jak i na ich zawartości. Na końcu warto zdefiniować metody umożliwiające dodawanie i usuwanie elementów wchodzących w skład drzewa.
Opis wzorca myślnik ćwiczenie czwarte. Nagranie jest tożsame z treścią.
Kompozyt może być wykorzystany na przykład w programach graficznych, gdzie możemy stworzyć obiekt składający się wielu składowych obiektów. Kiedy następnie chcemy przykładowo zmienić rozmiar całego obiektu, rozmiar poszczególnych elementów składowych zmieni się proporcjonalnie. Kompozyt często stosuje się wraz z Łańcuchem Zobowiązań, który umożliwia odsyłanie odpowiedzi do nadrzędnych komponentów, co daje razem możliwość przemieszczania się danych zarówno w kierunku coraz prostszych elementów, jak również w kierunku odwrotnym. Proste elementy wchodzące w skład Kompozytu mogą być implementowane jako Pyłki, co daje możliwość ograniczenia pamięci RAM do przeprowadzania operacji. Iiteratory pozwalają na sekwencyjne przemieszczanie się po elementach Kompozytu.
Struktura mostu
Widoczny jest schemat blokowy dotyczący zależności w strukturze Mostu. Schemat zawiera trzy panele w części środkowej połączone z trzema z lewej i dwoma z prawej strony. Centrum schematu wypełniają trzy panele z napisami od góry Client poniżej Abstraction implementation feature 1 feature 2 na dole panel Refined Abstraction ,feature N zależny od poprzedniego. Pierwszy i ostatni łączy się za pomocą strzałek z trzema panelami z lewej strony. Opisane są jako i.method 1 i.method 2, i.method 3, i.method N . Po prawej stronie schematu widoczne są dwa panele niższy wskazuje na Concrete Implementations a wyższy panel opisany jest jako Interface Implementation method1 method 2 method 3.
Przykładowy kod
Objaśnienie 1: Przykład implementacji Mostu na przykładzie aplikacji obsługującej piloty do różnych urządzeń, Python
Objaśnienie 2: Import niezbędnych bibliotek
Nowy wers from abc import ABC przecinek abstractmethod
Objaśnienie 3: Tworzenie abstrakcji
Nowy wers class RemoteControl otwarcie nawiasu okrągłego Device zamknięcie nawiasu okrągłego dwukropek
Nowy wers def podkreślnik init podkreślnik otwarcie nawiasu okrągłego self przecinek device dwukropek Device zamknięcie nawiasu okrągłego dwukropek
Nowy wers self kropka device równa się device
Nowy wers def togglePower otwarcie nawiasu okrągłego zamknięcie nawiasu okrągłego dwukropek
Nowy wers if otwarcie nawiasu okrągłego device kropka isEnabled otwarcie nawiasu okrągłego zamknięcie podwójnego nawiasu okrągłego dwukropek
Nowy wers device kropka disable otwarcie nawiasu okrągłego zamknięcie nawiasu okrągłego
Nowy wers else dwukropek
Nowy wers device kropka enable otwarcie nawiasu okrągłego zamknięcie nawiasu okrągłego
Nowy wers def volume Down otwarcie nawiasu okrągłego zamknięcie nawiasu okrągłego dwukropek
Nowy wers device kropka setVolume otwarcie nawiasu okrągłego device kropka getVolume otwarcie nawiasu okrągłego zamknięcie nawiasu okrągłego minus dziesięć zamknięcie nawiasu okrągłego
Nowy wers def volume Up otwarcie nawiasu okrągłego zamknięcie nawiasu okrągłego dwukropek
Nowy wers device kropka setVolume otwarcie nawiasu okrągłego device kropka getVolume otwarcie nawiasu okrągłego zamknięcie nawiasu okrągłego plus dziesięć zamknięcie nawiasu okrągłego
Nowy wers def channelDown otwarcie nawiasu okrągłego zamknięcie nawiasu okrągłego dwukropek
Nowy wers device kropka setChannel otwarcie nawiasu okrągłego devicekropka getChannel otwarcie nawiasu okrągłego zamknięcie nawiasu okrągłego minus 1 zamknięcie nawiasu okrągłego
Nowy wers def ChannelUp otwarcie nawiasu okrągłego zamknięcie nawiasu okrągłego dwukropek
Nowy wers device kropka set Channel otwarcie nawiasu okrągłego device kropka get Channel otwarcie nawiasu okrągłego zamknięcie nawiasu okrągłego plus jeden zamknięcie nawiasu okrągłego
Objaśnienie 4: Definiowanie implementacji
Nowy wers class Device otwarcie nawiasu okrągłego ABC zamknięcie nawiasu okrągłego dwukropek
Nowy wers def podkreślnik init podkreślnik otwarcie nawiasu okrągłego self przecinek enableState równa się None przecinek volume równa się None przecinek channel równa się None zamknięcie nawiasu okrągłego dwukropek
Nowy wers self kropka enableState równa się enableState
Nowy wers self kropka volume równa się volume
Nowy wers self kropka volume równa się enableState
Nowy wers def isEnabled otwarcie nawiasu okrągłego self zamknięcie nawiasu okrągłego dwukropek
Nowy wers pass
Nowy wers def enable otwarcie nawiasu okrągłego self zamknięcie nawiasu okrągłego dwukropek
Nowy wers pass
Nowy wers def disable otwarcie nawiasu okrągłego self zamknięcie nawiasu okrągłego
Nowy wers pass
Nowy wers def getVolume otwarcie nawiasu okrągłego self zamknięcie nawiasu okrągłego dwukropek
Nowy wers pass
Nowy wers def setVolume otwarcie nawiasu okrągłego self przecinek percent zamknięcie nawiasu okrągłego dwukropek
Nowy wers pass
Nowy wers def getChannel otwarcie nawiasu okrągłego self zamknięcie nawiasu okrągłego dwukropek
Nowy wers pass
Nowy wers def setChannel otwarcie nawiasu okrągłego self przecinek channel zamknięcie nawiasu okrągłego dwukropek
Nowy wers pass
Objaśnienie 5: Wszystkie urządzenia są zgodne pod względem interfejsu
Nowy wers class Tv otwarcie nawiasu okrągłego Device zamknięcie nawiasu okrągłego dwukropek
Nowy wers def podkreślnik init podkreślnik otwarcie nawiasu okrągłego self przecinek enableState równa się True przecinek volume równa się pięćdziesiąt przecinek channel równa się jeden zamknięcie nawiasu okrągłego dwukropek
Nowy wers self kropka enableState równa się enableState
Nowy wers self kropka volume równa się volume
Nowy wers self kropka volume równa się enableState
Nowy wers def isEnabled otwarcie nawiasu okrągłego self zamknięcie nawiasu okrągłego dwukropek
Nowy wers return self kropka enableState
Nowy wers def enable początek nawiasu okrągłego self koniec nawiasu okrągłego dwukropek
Nowy wers self kropka enableState równa się True
Nowy wers return self kropka enableState
Nowy wers def disable początek nawiasu okrągłego self koniec nawiasu okrągłego
Nowy wers self kropka enableState równa się False
Nowy wers return self kropka enableState
Nowy wers def getVolume początek nawiasu okrągłego self koniec nawiasu okrągłego dwukropek
Nowy wers return self kropka volume
Nowy wers def setVolume początek nawiasu okrągłego self przecinek percent koniec nawiasu okrągłego dwukropek
Nowy wers if volume równa się sto dwukropek
Nowy wers self kropka volume równa się volume
Nowy wers else dwukropek
Nowy wers self kropka volume równa się volume plus percent
Nowy wers return self kropka volume
Nowy wers def getChannel początek nawiasu okrągłego self koniec nawiasu okrągłego dwukropek
Nowy wers return self kropka channel
Nowy wers def setChannel początek nawiasu okrągłego self przecinek channel koniec nawiasu okrągłego dwukropek
Nowy wers self kropka channel równa się channel
Nowy wers return self kropka channel
Nowy wers class Radio początek nawiasu okrągłego Device koniec nawiasu okrągłego dwukropek
Nowy wers def podkreślnik init podkreślnik początek nawiasu okrągłego self przecinek enableState równa się True przecinek volume równa się pięćdziesiąt przecinek channel równa się jeden koniec nawiasu okrągłego dwukropek
Nowy wers self kropka enableState równa się enableState
Nowy wers self kropka volume równa się volume
Nowy wers self kropka volume równa się enableState
Nowy wers def isEnabled początek nawiasu okrągłego self koniec nawiasu okrągłego dwukropek
Nowy wers return self kropka enableState
Nowy wers def enable początek nawiasu okrągłego self koniec nawiasu okrągłego dwukropek
Nowy wers self kropka enableState równa się True
Nowy wers return self kropka enableState
Nowy wers def disable początek nawiasu okrągłego self koniec nawiasu okrągłego
Nowy wers self kropka enableState równa się False
Nowy wers return self kropka enableState
Nowy wers def getVolume początek nawiasu okrągłego self koniec nawiasu okrągłego dwukropek
Nowy wers return self kropka volume
Nowy wers def setVolume początek nawiasu okrągłego self przecinek percent koniec nawiasu okrągłego dwukropek
Nowy wers if volume równa się sto dwukropek
Nowy wers self kropka volume równa się volume
Nowy wers else dwukropek
Nowy wers self kropka volume równa się volume plus percent
Nowy wers return self kropka volume
Nowy wers def getChannel początek nawiasu okrągłego self koniec nawiasu okrągłego dwukropek
Nowy wers return self kropka channel
Nowy wers def setChannel początek nawiasu okrągłego self przecinek channel koniec nawiasu okrągłego dwukropek
Nowy wers self kropka channel równa się channel
Nowy wers return self kropka channel
Objaśnienie 6: Z powyższego kodu może korzystać kod kliencki w następujący sposób
tv równa się Tv początek nawiasu okrągłego koniec nawiasu okrągłego
Nowy wers remote równa się RemoteControl początek nawiasu okrągłego tv koniec nawiasu okrągłego
Nowy wers remote kropka togglePower początek nawiasu okrągłego koniec nawiasu okrągłego
Nowy wers radio równa się Radio początek nawiasu okrągłego koniec nawiasu okrągłego
Nowy wers remote równa AdvancedRemoteControl początek nawiasu okrągłego radio koniec nawiasu okrągłego
Opis strukturalny trzy myślnik struktura i kod. Opis wzorca:
Opis wzorca myślnik ćwiczenie pierwsze. Nagranie jest tożsame z treścią.
Most to kolejny przykład wzorca strukturalnego, który wykorzystuje się, aby rozdzielić dużą i skomplikowaną klasę lub zestaw spokrewnionych klas na dwie hierarchie: abstrakcję (logika wysokiego poziomu, np. GUI aplikacji) oraz implementację (logikę niskiego poziomu, np. API).
Most (Bridge) wykorzystuje się w momencie, gdy jakaś klasa (lub zestaw klas) jest wykorzystywana do obsługi wielu różnych środowisk (systemów operacyjnych czy bazodanowych) i jednocześnie obsługuje w nich analogiczne operacje. Taka klasa jest wtedy bardzo rozbudowana, a w przypadku dodawania wsparcia dla kolejnego środowiska należy dodatkowo ją rozbudować poprzez zaimplementowanie analogicznych metod do tych, które są wykorzystywane w pozostałych środowiskach, co zwiększa jej skomplikowanie, zmniejsza jej czytelność, a tym samym zwiększa koszt utrzymania kodu. Każde kolejne dodanie funkcjonalności rozszerza tą klasę w sposób geometryczny.
Opis wzorca myślnik ćwiczenie drugie. Nagranie jest tożsame z treścią.
Most wykorzystuje się, aby uprościć strukturę bardzo rozbudowanej klasy. Robi się to poprzez jej podział na tak zwaną abstrakcję, czyli wysokopoziomowy interfejs wspólny dla wszystkich obsługiwanych środowisk oraz implementację, gdzie opisane są niskopoziomowe operacje specyficzne dla danego środowiska. Można to pokazać na przykładzie programu pracującego z bazami danych: abstrakcja, czyli GUI naszego programu, pozwala nam przeszukiwać, dodawać i usuwać dane z bazy. Będziemy go używać identycznie niezależnie od systemu bazodanowego, jaki jest aktualnie używany. Implementacja natomiast będzie zawierać informacje, w jaki sposób wykonać operacje, które przekazuje abstrakcja na wybranym systemie bazodanowym, aby niezależnie od zastosowanego systemu klient uzyskał ten sam rezultat. Oznacza to, że jeśli nasz program ma obsługiwać 4 systemy bazodanowe, to dla każdego z nich będzie istnieć odpowiednia warstwa w implementacji. Takie rozwiązanie znacząco ułatwia późniejsze rozszerzanie funkcjonalności kodu i obniża koszty jego utrzymania. Uczestnicy: Abstrakcja} – zawiera w sobie logikę wysokiego poziomu i stanowi ona interfejs, przez który klient może komunikować się z programem. Implementacja – zawiera w sobie logikę niskiego poziomu, stanowi ona często interfejs między Abstrakcją a wybranym środowiskiem, które jest wykorzystywane. Abstrakcja, jako klasa zawierająca logikę wysokiego poziomu, jest wykorzystywana do tworzenia interfejsów użytkownika. Zawiera ona w sobie metody wykorzystywane bezpośrednio przez użytkownika do przeprowadzenia pewnej operacji. Z reguły zawiera ona w sobie wyłącznie informacje o tym, jaka operacja ma zajść po wykonaniu pewnych działań przez użytkownika oraz połączenie z odpowiednią klasą implementacyjną. Ważne jest również, że Abstrakcja wie, z jakiej {Implementacji} ma skorzystać. Informacje wysłane przez Abstrakcję trafiają do Implementacji, gdzie wykonywane są wszystkie niskopoziomowe operacje związane z komunikacją z konkretnym środowiskiem, wykonywaniem konkretnych operacji i wysyłaniu informacji zwrotnych do Abstrakcji. Dzięki temu rozwiązaniu użytkownik może korzystać z aplikacji w identyczny sposób, niezależnie od platformy, z której korzysta.
Opis wzorca myślnik ćwiczenie trzecie. Nagranie jest tożsame z treścią.
Wzorzec projektowy jakim jest Most umożliwia tworzenie programów i aplikacji niezależnych od platformy. Kod klienta komunikuje się jedynie z Abstrakcją i nie musi mieć do czynienia ze szczegółami platformy. Można wprowadzać nowe Abstrakcje i Implementacje niezależnie od siebie. Z uwagi na oddzielenie Abstrakcji i Implementacji można pracować na nich niezależnie. Most może okazać się skomplikowany i trudny do zaimplementowania w przypadku bardzo zwartych, spójnych klas. Najpierw wyznacza się płaszczyzny klas i określa, która z nich powinna być Abstrakcją, a która Implementacją. W Abstrakcji powinny znaleźć się operacje, które będzie wykorzystywał kod klienta lub użytkownik. Zdefiniować należy także wszystkie operacje wspólne dla wszystkich platform i również umieścić je w Abstrakcji. Następnie tworzy się klasy Implementacji – powinno być ich tyle, ile platform. Można też stworzyć jedną klasę i następnie wyróżniać podklasy. Ważne, by były one spójne z interfejsem Abstrakcji. Umieszcza się w nich wszystkie metody, które nie są niezbędne do wykonywania na poziomie Abstrakcji oraz te, których implementacja na różnych platformach się różni.
Opis wzorca myślnik ćwiczenie czwarte. Nagranie jest tożsame z treścią.
Most jest idealnym wzorcem projektowym do zastosowania wszędzie tam, gdzie ten sam program ma być wykorzystywany na różnych platformach i pełnić na nich analogiczne funkcje. Przykładem mogą być przeglądarki internetowe na różnych systemach operacyjnych – z poziomu użytkowania wykonywane są te same operacje opisane w Abstrakcji, z kolei niskopoziomowe metody odpowiedzialne za prawidłowe funkcjonowanie przeglądarki na danym systemie operacyjnym opisane są w Implementacji. Most może być wykorzystywany wraz z Fabryką Abstrakcyjną, zwłaszcza gdy dana Abstrakcja może działać wyłącznie z wybranymi Implementacjami. Fabryka Abstrakcyjna umożliwia zhermetyzowanie tej Abstrakcji z obsługiwanymi przez nią Implementacjami i ukrycie tych zawiłości przed kodem klienta. Można łączyć ze sobą wzorce Most i Budowniczy: klasa Kierownika będzie pełniła funkcję Abstrakcji, z kolei klasa Budowniczego – Implementacji.
Powrót do spisu treściPowrót do spisu treści
2. Dokumentacja związana ze wzorcami projektowymi – część 2
Wzorzec behawioralny jeden myślnik struktura i kod.
Struktura obserwatora
Widoczny jest schemat przedstawiający strukturę obserwatora. Składa się z prostokątów połączonych ze sobą przerywanymi liniami bądź strzałkami. Po lewej stronie umieszczone zostały dwa prostokąty z napisami: foreach (s in subcribers) s.update(this) oraz mainState = newState notify Subscribers (). Po prawej dwa prostokąty opatrzone tytułami oraz treścią. Pierwszy z nich: Interface Subscriber + update(context). Drugi: Concrete Subscribers .... + update(context). Pośrodku znajduje się prostokąt z tytułem Publisher oraz treścią: - subscribers: Subscriber [] - main State+ subscribe(s: Subscriber) + unsubscriber(s: Subscriber) +notifySubscribers() +mainBusinessLogic(). Pod nim znajduje się prostokąt z napisem: s = new ConcreteSubscriber() publisher.subscribe(s). Ostatni kafelek jest z napisem Client.
Przykładowy kod
Objaśnienie 1: Przykład Obserwatora na kodzie koncepcyjnym napisanym w Pythonie
Nowy wers from abc import ABC przecinek abstractmethod
Nowy wers from random import randrange
Nowy wers from typing import List
Objaśnienie 2: Import niezbędnych bibliotek
Nowy wers class Subject nawias okrągły ABC koniec nawiasu okrągłego dwukropek
Nowy wers małpa abstractmethod
Nowy wers def add nawias okrągły self przecinek subscriber dwukropek Subscriber koniec nawiasu okrągłego minus zamknięcie nawiasu ostrokątnego None dwukropek
Nowy wers pass
Objaśnienie 3: Definiujemy interfejs z zestawem metod do zarządzania subskrypcjami
Nowy wers małpa abstractmethod
Nowy wers def remove nawias okrągły self przecinek subscriber dwukropek Subscriber koniec nawiasu minus zamknięcie nawiasu ostrokątnego None dwukropek
Nowy wers pass
Nowy wers małpa abstractmethod
Nowy wers def notify nawias okrągły self koniec nawiasu minus zamknięcie nawiasu ostrokątnego None dwukropek
Nowy wers pass
Objaśnienie 4: Tutaj definiujemy konkretne wydarzenie oraz metody subskrybowania tego wydarzenia – to jest Obserwator konkretnego zdarzenia
Nowy wers class ConcreteSubject nawias okrągły Subject koniec nawiasu okrągłego dwukropek
Nowy wers podkreślnik state dwukropek int znak równości None
Nowy wers podkreślnik subscribers dwukropek List nawias kwadratowy Subscribers koniec nawiasu kwadratowego znak równości nawias kwadratowy koniec nawiasu
Nowy wers def attach nawias okrągły self przecinek subscriber dwukropek Subscriber koniec nawiasu minus koniec nawiasu ostrokątnego None dwukropek
Nowy wers print nawias okrągły cudzysłów Subject dwukropek Attached an subscriber kropka cudzysłów koniec nawiasu
Nowy wers self kropka podkreślnik subscribers kropka append nawias okrągły subscriber koniec nawiasu
Nowy wers def detach nawias okrągły self przecinek subscriber dwukropek Subscriber koniec nawiasu minus koniec nawiasu ostrokątnego None dwukropek
Nowy wers self kropka podkreślnik subscribers kropka remove nawias okrągły subscriber koniec nawiasu
Nowy wers def notify nawias okrągły self koniec nawiasu minus koniec nawiasu ostrokątnego None dwukropek
Nowy wers print nawias okrągły cudzysłów Subject dwukropek Notifying subscribers trzy kropki cudzysłów koniec nawiasu
Nowy wers for subscriber in self kropka podkreślnik subscribers dwukropek
Nowy wers subscriber kropka update nawias okrągły self koniec nawiasu
Nowy wers def some podkreślnik business podkreślnik logic nawias okrągły self koniec nawiasu minus koniec nawiasu ostrokątnego None dwukropek
Nowy wers print nawias okrągły cudzysłów ukośnik nSubject dwukropek I’m doing something important kropka cudzysłów koniec nawiasu
Nowy wers self kropka podkreślnik state znak równości randrange nawias okrągły zero przecinek dziesięć koniec nawiasu
Nowy wers print nawias okrągły f cudzysłów Subject dwukropek My state has just changed to dwukropek nawias klamrowy self kropka podkreślnik state koniec nawiasu klamrowego cudzysłów koniec nawiasu okrągłego
Nowy wers self kropka notify nawias okrągły koniec nawiasu
Objaśnienie 5: Definiujemy interfejs Subskrybenta
Nowy wers class Subscriber nawias okrągły ABC koniec nawiasu dwukropek
Nowy wers małpa abstractmethod
Nowy wers def update nawias okrągły self przecinek subject dwukropek Subject koniec nawiasu minus koniec nawiasu ostrokątnego None dwukropek
Nowy wers pass
Objaśnienie 6: Następnie definiowani są konkretni Subskrybenci
Nowy wers class ConcreteSubscriberA nawias okrągły Subscriber koniec nawiasu dwukropek
Nowy wers def update nawias okrągły self przecinek subject dwukropek Subject koniec nawiasu minus koniec nawiasu ostrokątnego None dwukropek
Nowy wers if subject kropka podkreślnik state znak mniejszości cyfra trzy dwukropek
Nowy wers print nawias okrągły cudzysłów ConcreteSubscriberA dwukropek Reacted to the event cudzysłów koniec nawiasu
Nowy wers class ConcreteSubscribersB nawias okrągły Subscriber koniec nawiasu dwukropek
Nowy wers def update nawias okrągły self przecinek subject dwukropek Subject koniec nawiasu minus koniec nawiasu ostrokątnego None dwukropek
Nowy wers if subject kropka podkreślnik state dwa znaki równości zero or subject kropka podkreślnik znak większości znak równości cyfra dwa dwukropek
Nowy wers print nawias okrągły cudzysłów ConcreteSubscriberB dwukropek Reacted to the event cudzysłów koniec nawiasu
Objaśnienie 7: Tu zdefiniowany został kod kliencki
Nowy wers if podkreślnik name podkreślnik dwa razy znak równości cudzysłów podkreślnik main podkreślnik cudzysłów dwukropek
Nowy wers subject znak równości ConcreteSubject nawias okrągły koniec nawiasu
Nowy wers subscriber podkreślnik a znak równości ConcreteSubscriberA nawias okrągły koniec nawiasu
Nowy wers subject kropka attach nawias okrągły subscriber podkreślnik a koniec nawiasu
Nowy wers subscriber podkreślnik b znak równości ConcreteSubscriberB nawias okrągły koniec nawiasu
Nowy wers subject kropka attach nawias okrągły subscriber podkreślnik b koniec nawiasu
Nowy wers subject kropka some podkreślnik business podkreślnik logic nawias okrągły koniec nawiasu
Nowy wers subject kropka some podkreślnik business podkreślnik logic nawias okrągły koniec nawiasu
Nowy wers subject kropka detach nawias okrągły subscriber podkreślnik a koniec nawiasu
Nowy wers subject kropka some podkreślnik business podkreślnik logic nawias okrągły koniec nawiasu
Wzorzec behawioralny jeden myślnik struktura i kod
Opis wzorca myślnik ćwiczenie pierwsze. Nagranie jest tożsame z treścią.
Obserwator jest przykładem wzorca czynnościowego inaczej behawioralnego. Jego przeznaczeniem jest stworzenie mechanizmu śledzącego stan jakiegoś obiektu, np. czy istnieje, czy zniknął, jaka jest wartość jednego z jego atrybutów, czy wartość tego atrybutu uległa zmianie i informowanie o tej zmianie inne obiekty lub struktury. Inne nazwy pod którymi występuje .Inne nazwy pod którymi występuje ten wzorzec to; Event‑Subscriber, Listener, . Observer. Stosowany jest do rozwiązania problemu monitorowania stanu danego obiektu i subskrybowania o tej zmianie, aby z jednej strony obiekt zainteresowany stanem innego obiektu nie miał potrzeby ciągłego sprawdzania stanu, a z drugiej strony, by obiekty niezainteresowane stanem tego obiektu nie były zaśmiecane tą informacją.
Opis wzorca myślnik ćwiczenie drugie. Nagranie jest tożsame z treścią.
Ten wzorzec projektowy pełni rolę subskrypcji, w której jeden z obiektów powinien wykonywać jakąś instrukcję zależnie od stanu innego obiektu, dlatego musi na bieżąco znać jego stan. Obserwator w tym momencie jest strukturą, która monitoruje stan danego obiektu i w razie jego zmiany informuje o tym wszystkie obiekty, które subskrybują tę informację. Znajduje on zastosowanie szczególnie tam, gdzie jest większa liczba obiektów, których funkcjonalność zależy od stanu monitorowanego obiektu, a z drugiej strony informacja ta nie powinna być udostępniana obiektom, które nie muszą zdawać sobie sprawy ze zmiany stanu danego obiektu. Dodatkowo Obserwator daje możliwość dodania nowych subskrybentów lub usunięcia tych, którzy już nie chcą korzystać z subskrypcji. Uczestnicy; Subskrybent – czyli klasa (lub obiekt), która może wykorzystywać informacje o stanie innego obiektu do wykonywania konkretnych operacji. Subskrybent może zapisać się na subskrypcję, wypisać się z niej oraz definiuje interfejs, po jakim informacje o zmianie stanu mają do niego trafiać. Obserwator czyli klasa (lub obiekt) odpowiedzialna za monitorowanie stanu określonego obiektu, interfejsu lub aplikacji i informowanie o tych zmianach subskrybentów. W Obserwatorze zdefiniowane są metody dodawania i usuwania subskrybentów, jak również metody przekazywania informacji do nich o zajściu określonego zdarzenia. Publikujący czyli klasa (lub obiekt), która jest monitorowana i która informuje Obserwatora o zmianie stanu.
Opis wzorca myślnik ćwiczenie trzecie. Nagranie jest tożsame z treścią.
Obserwator ściąga z subskrybenta odpowiedzialność za monitorowanie stanu interesującego go obiektu, co więcej, subskrybent może w dowolnej chwili zrezygnować z subskrypcji. Obserwator z kolei może śledzić stan obiektu w imieniu wielu innych obiektów, co ma ogromne znaczenie, z jednej strony bowiem każdy z zainteresowanych obiektów nie musi śledzić danego obiektu z osobna (więc nie musi mieć do tego specjalnych metod), z drugiej strony lista subskrybentów jest dynamiczna, co pozwala zwiększyć elastyczność aplikacji jak również lepiej zarządzać zasobami. Dodatkowo, to rozwiązanie sprawia, że Publikujący informuje o zmianie stanu jedynie Obserwatora i nie musi mieć skonfigurowanych interfejsów do każdej zależnej od niego klasy lub obiektu. Zaletą tego wzorca projektowego jest to, że można z łatwością dodawać nowe klasy wdrażające nowe funkcjonalności bez konieczności zmian w kodzie Obserwatora i odwrotnie. Ponadto dynamiczna metoda subskrypcji daje możliwość elastycznego tworzenia i działania aplikacji, gdyż niezbędne zależności mogą tworzyć się i usuwać automatycznie w trakcie działania aplikacji. Wadą takiego rozwiązania jest to, że nie ma możliwości kontrolowania kolejności, w jakiej subskrybenci otrzymają informacje o zmianie stanu monitorowanego obiektu.
Opis wzorca myślnik ćwiczenie czwarte. Nagranie jest tożsame z treścią.
Zastanów się, które elementy logiki biznesowej są zależne od stanu innych obiektów, a które nie. Te elementy, które wykazują takie zależności, mogą zostać Subskrybentami, dla których można przygotować klasę Obserwatora. Kolejnym etapem będzie stworzenie interfejsów w klasach Subskrybentów i w klasach Obserwatorów, umożliwiających ich wzajemną komunikację. Następnym krokiem będzie stworzenie metod zarządzania Subskrybentami, takich jak dodawanie i usuwanie Subskrybentów. Ostatnim etapem będzie przygotowanie metod powiadamiających Subskrybentów o zarejestrowaniu zmiany stanu monitorowanego obiektu. W życiu codziennym z Obserwatorem mamy do czynienia, gdy subskrybujemy jakiegoś bloga lub zapisujemy się na newsletter .Obserwator będzie informował o nowych zdarzeniach i przysyłał artykuły na skrzynkę mailową. Wzorce: Łańcuch Zobowiązań, Mediator, Obserwator i Polecenie są stosowane do obsługi zależności i przepływu informacji między innymi obiektami, różni je jedynie ich rola i zastosowanie. Obserwator i Mediator mają bardzo podobną strukturę i mogą być stosowane wspólnie lub zamiennie, mimo że mają one nieco odmienne cele: Mediator likwiduje sieć zależności między elementami kodu i uzależnia wszystkie elementy od obiektu Mediatora; Obserwator zaś jest używany do tworzenia jednokierunkowych połączeń między obiektami, w których jedne zależą od drugich.
Wzorzec behawioralny dwa myślnik struktura i kod.
Struktura Metody szablonowej
Schemat przedstawia strukturę Metody szablonowej. Składa się z czterech kafli powiązanych ze sobą. Pierwszy, główny zatytułowany jest AbstractClass … + templateMethod() + step1() + step2() +step3() +step4(). Pod nim znajdują się połączone z nim strzałką dwa następne kafle: ConcreteClass1 … + step3() + step4() oraz ConcreteClass1 … + step1() +step2() + step3() +step4(). Z abstractClass połączony jest ostatni z kafli, znajdujący się po prawej stronie: step1() if (step2()) {step3()} else {step4()}.
Przykładowy kod
Objaśnienie 1: Metoda szablonowa na przykładzie fragmentu kodu prostej gry napisanej w Phytonie
Objaśnienie 2: Import niezbędnych bibliotek
Nowy wers from abc import ABC przecinek abstractmethod
Objaśnienie 3: Klasa abstrakcyjna definiuje metodę szablonową zawierającą szkielet jakiegoś algorytmu skomponowany w formie zestawu prostych metod i abstrakcyjnych działań. Konkretne podklasy implementują te działania, ale nie zmieniają metody szablonowej
Nowy wers class GameAI nawias okrągły ABC koniec nawiasu dwukropek
Objaśnienie 4: Metoda szablonowa
Nowy wers def turn nawias okrągły self koniec nawiasu dwukropek
Nowy wers collectResources nawias okrągły koniec nawiasu
Nowy wers buildStructures nawias okrągły koniec nawiasu
Nowy wers buildUnits nawias okrągły koniec nawiasu
Nowy wers attack nawias okrągły koniec nawiasu
Objaśnienie 5: Niektóre etapy mogą zostać zaimplementowane już w klasie bazowej
Nowy wers def collectResources nawias okrągły self koniec nawiasu dwukropek
Nowy wers for s in self kropka builtStructures dwukropek
Nowy wers s kropka collect nawias okrągły koniec nawiasu
Objaśnienie 6: Inne mogą być zdefiniowane jako abstrakcyjne
Nowy wers małpa abstractmethod
Nowy wers def buildStructure nawias okrągły self koniec nawiasu dwukropek
Nowy wers pass
Nowy wers małpa abstractmethod
Nowy wers def buildUnits nawias okrągły self koniec nawiasu dwukropek
Nowy wers pass
Objaśnienie 7: Klasa szablonowa może mieć wiele metod szablonowych
Nowy wers def attack nawias okrągły self koniec nawiasu dwukropek
Nowy wers enemy znak równości closestEnemy nawias okrągły koniec nawiasu
Nowy wers if nawias okrągły enemy dwa znaki równości None koniec nawiasu dwukropek
Nowy wers sendScouts nawias okrągły map kropka center koniec nawiasu
Nowy wers else dwukropek
Nowy wers sendWarriors nawias okrągły enemy kropka position koniec nawiasu
Nowy wers małpa abstractmethod
Nowy wers def sendScouts nawias okrągły position koniec nawiasu dwukropek
Nowy wers pass
Nowy wers małpa abstractmethod
Nowy wers def sendWarriors nawias okrągły position koniec nawiasu
Nowy wers pass
Objaśnienie 8: Konkretne klasy muszą zaimplementować wszystkie abstrakcyjne działania klasy szablonowej oraz nie mogą nadpisać samej metody szablonowej. Mogą natomiast nadpisywać pewne domyślne implementacje
Nowy wers class OrcsAI nawias okrągły GameAI koniec nawiasu dwukropek
Nowy wers def buildStructures nawias okrągły koniec nawiasu dwukropek
Nowy wers if resources dwukropek
Nowy wers build nawias okrągły building koniec nawiasu
Nowy wers def buildUnits nawias okrągły koniec nawiasu dwukropek
Nowy wers if resources dwukropek
Nowy wers if scouts dwa znaki równości zero dwukropek
Nowy wers build nawias okrągły scout koniec nawiasu
Nowy wers scouts plus znak równości jeden
Nowy wers else dwukropek
Nowy wers build nawias okrągły warrior koniec nawiasu
Nowy wers warriors plus znak równości jeden
Nowy wers def sendScouts nawias okrągły position koniec nawiasu dwukropek
Nowy wers if len nawias okrągły scouts koniec nawiasu znak większości zero dwukropek
Nowy wers scouts kropka send nawias okrągły position koniec nawiasu
Nowy wers def sendWarriors nawias okrągły position koniec nawiasu dwukropek
Nowy wers if len nawias okrągły warriors koniec nawiasu znak większości pięć dwukropek
Nowy wers warriors kropka send nawias okrągły position koniec nawiasu
Objaśnienie 9: Potwory nie zbierają surowców i nie budują budynków ani jednostek, nie korzystają zatem z tych metod i można je nadpisać.
Nowy wers class MonstersAI nawias okrągły GameAI koniec nawiasu dwukropek
Nowy wers def collectResources nawias okrągły koniec nawiasu
Nowy wers pass
Nowy wers def buildStructures nawias okrągły self koniec nawiasu dwukropek
Nowy wers pass
Nowy wers def buildUnits nawias okrągły self koniec nawiasu dwukropek
Nowy wers pass
Wzorzec behawioralny dwa myślnik struktura i kod
Opis wzorca myślnik ćwiczenie pierwsze. Nagranie jest tożsame z treścią.
Metoda szablonowa to kolejny wzorzec czynnościowy. Jego przeznaczeniem jest stworzenie możliwości tworzenia pochodnych klasy pełniącej rolę szablonu, w których to owe podklasy mogą nadpisywać i dodawać pewne elementy i funkcjonalności bez zmiany struktury szablonu .Inna nazwa dla tego wzorca (ang.Template Method).Uproszczenie kodu dla klas posiadających wiele wspólnych metod, które jednak mają różne zastosowania poprzez wydzielenie wspólnego kodu do klasy pełniącej rolę szablonu.
Opis wzorca myślnik ćwiczenie drugie. Nagranie jest tożsame z treścią.
Metodę Szablonową stosuje się, aby wydzielić kod, który może być współdzielony przez kilka innych klas, do jednej, pełniącej rolę szablonu. Następnie tworzy się klasy dziedziczące po szablonie, dzięki czemu ten sam kod jest używany w każdej z tych klas. Następnie, w celu wyspecjalizowania klas pochodnych do wykonywania konkretnych operacji metody szablonu, można nadpisywać lub dodawać kolejne. Metoda Szablonowa jest implementowana wszędzie tam, gdzie istnieje wiele klas o podobnej funkcjonalności i korzysta się z tych samych metod, aby zmniejszyć ilość powielonego kodu, zwiększyć jego czytelność i zmniejszyć koszty jego utrzymania. Uczestnicy: Klasa Abstrakcyjna – pełni rolę szablonu, ma w sobie zdefiniowane metody, które mogą być wykorzystane lub zmienione przez dziedziczącą po niej Konkretną Klasę. Konkretna Klasa – klasa wyspecjalizowana w wykonywaniu pewnych operacji, definiuje w sobie jedynie specyficzne metody, niestosowane przez inne klasy, pozostałe metody dziedziczy od Klasy Abstrakcyjnej. Klasa Abstrakcyjna jako szablon zbiera w sobie kod wspólny dla Konkretnych Klas. Z racji tego, że jest on zdefiniowany w jednym miejscu, wystarczy zmodyfikować go jedynie tutaj, aby zmiany w nim wpływały na wszystkie dziedziczące po niej Konkretne Klasy – nie ma konieczności modyfikowania każdej Konkretnej Klasy z osobna. Ponadto takie rozwiązanie jest elastyczne, gdyż Konkretna Klasa może zawsze nadpisać metody Klasy Abstrakcyjnej w razie potrzeby, nie modyfikując jednocześnie kodu Klasy Abstrakcyjnej, a zatem nadpisanie metody w jednej Konkretnej Klasie nie powoduje zmian zachowania w innej Konkretnej Klasie dziedziczącej po tej samej Klasie Abstrakcyjnej.
Opis wzorca myślnik ćwiczenie trzecie. Nagranie jest tożsame z treścią.
Metoda szablonowa umożliwia nadpisywanie jedynie części metod lub całych algorytmów, co zwiększa odporność kodu na szkody wywołane zmianami jego poszczególnych fragmentów. Pozwala znacząco odchudzić kod poprzez zamknięcie wspólnej jego części w Klasie Abstrakcyjnej. Szkielet Klasy Abstrakcyjnej może stanowić ograniczenie dla niektórych rozwiązań. Metody Szablonowe mogą być trudne do utrzymywania w przypadku bardzo złożonych i skomplikowanych algorytmów o dużej ilości etapów. W implementacji wzorca zaczyna się od wydzielenia kodu wspólnego dla szeregu klas o zbliżonych funkcjonalnościach. W przypadku algorytmu bierze się pod uwagę podzielenie go na etapy w taki sposób, by jak największa jego część znalazła się w Klasie Abstrakcyjnej. Tworzy się Klasę Abstrakcyjną, a następnie dziedziczące po niej Konkretne Klasy. W nich możesz nadpisać niektóre metody lub dodać nowe. Ważnym jest, aby dla każdej wersji algorytmu lub funkcjonalności dodać osobną klasę dziedziczącą po Klasie Abstrakcyjnej.
Opis wzorca myślnik ćwiczenie czwarte. Nagranie jest tożsame z treścią.
Metoda Szablonowa może zostać wykorzystana do stworzenia programu zapisującego dane w różnych formatach lub konwertera z jednego formatu pliku w inny. Taki program będzie miał wiele metod, które będą wykorzystywane w każdej z klas odpowiedzialnych za obsługę konkretnego formatu pliku i które można wydzielić do Klasy Abstrakcyjnej. Metoda Wytwórcza to wyspecjalizowana wersja Metody Szablonowej, może ona także stanowić element większej Metody Szablonowej. Metoda Szablonowa i Strategia mogą realizować podobne cele. Jednak Metoda Szablonowa korzysta z mechanizmu dziedziczenia przez Konkretne Klasy właściwości Klasy Abstrakcyjnej, a Strategia wykorzystuje kompozycję obiektów. Dodatkowo Metoda Szablonowa operuje na klasach, a Strategia na obiektach.
Wzorzec behawioralny trzy myślnik struktura i kod.
Struktura łańcucha zobowiązań
Widoczny jest schemat blokowy dotyczący zależności w strukturze łańcucha zobowiązań. Schemat zawiera trzy panele po lewej stronie i cztery po prawej. Z lewej od góry panel Handler, base handler, concreatehandlers. Ostatni łączy się za pomocą strzałki z drugim, a on z kolei z pierwszym. Po prawej stronie panel Client połączony strzałką z panelem handler. Poniżej panel połączony przerywaną linią z wypisanym kolejno: ha jeden znak równości new handler a otwórz zamknij nawias okrągły. ha dwa znak równości new handler be otwórz zamknij nawias okrągły. ha trzy znak równości new handler ce otwórz zamknij nawias okrągły. Ha jeden kropka set next otwórz nawias ha dwa zamknij nawias okrągły. Ha dwa kropka set next otwórz nawias ha trzy zamknij nawias okrągły.
Nowy wers Prawy ukośnik prawy ukośnik trzy kropki
Następny wers Ha jeden kropka handle otwórz nawis request zamknij nawias okrągły. Panel poniżej zawiera zapis. If otwórz nawias okrągły next wykrzyknik znak równości null zamknij nawias okrągły
Nowy wers Next kropka handle otwórz nawias okrągły request zamknij nawias okrągły. Panel ostatni zawiera zapis. If otwórz nawias okrągły can handle otwórz nawias okrągły request zamknij nawias okrągły zamknij nawias okrągły otwórz nawias klamrowy
Nowy wers prawy ukośnik prawy ukośnik trzy kropki
Nowy wers Zamknij nawias klamrowy else otwórz nawias klamrowy
Nowy wers Parent dwukropek dwukropek handle otwórz nawias okrągły request zamknij nawias okrągły
Nowy wers zamknij nawias klamrowy. Poniżej widoczny jest kod
Objaśnienie pierwsze. Prezentacja Łańcucha zobowiązań na przykładzie kodu koncepcyjnego stworzonego w Pythonie
Pierwszy wers. Przykładowy kod
Objaśnienie drugie. Import niezbędnych bibliotek
Nowy wers From a be ce import a be ce przecinek abstractmethod
Nowy wers From typing import any przecinek optional
Objaśnienie trzecie. Interfejs Obiektu Obsługującego deklaruje metodę wykonującą żądanie oraz metodę budowania łańcucha Obiektów Obsługujących
Nowy wers Class handler otwórz nawias okrągły a be ce zamknij nawias okrągły dwukropek
Nowy wers Małpa abstractmethod
Nowy wers Def set podkreślnik next otwórz nawias okrągły przecinek handler dwukropek handler zamknij nawias okrągły minus zamknij nawias ostrokątny handler dwukropek
Nowy wers Pass
Nowy wers Małpa abstractmethod
Nowy wers Def handle otwórz nawias okrągły self przecinek request zamknij nawias okrągły minus zamknij nawias ostrokątny optional otwórz nawias kwadratowy es te er zamknij nawias kwadratowy dwukropek
Nowy wers Pass
Objaśnienie czwarte. Domyślny mechanizm tworzenia łańcucha może być zaimplementowany wewnątrz Bazowego Obiektu Obserwującego
Nowy wers Class abstracthandler otwórz nawias okrągły handler zamknij nawias okrągły dwukropek
Nowy wers Podkreślnik next podkreślnik handler dwukropek handler znak równości none
Nowy wers Def set podkreślnik next otwórz nawias okrągły self przecinek handler dwukropek handler zamknij nawias okrągły minus zamknij nawias ostrokątny handler dwukropek
Nowy wers Self kropka podkreślnik next podkreślnik handler znak równości handler
Nowy wers Return handler
Nowy wers Małpa abstractmethod
Nowy wers Def handle otwórz nawias okrągły self przecinek request dwukropek any zamknij nawias okrągły minus zamknij nawias ostrokątny es te er dwukropek
Nowy wers If self kropka podkreślnik next podkreślnik handler dwukropek
Nowy wers Return self kropka podkreślnik next podkreślnik handler kropka handle otwórz nawias okrągły request zamknij nawias okrągły
Nowy wers Return none
Objaśnienie piąte. Konkretne Obiekty Obsługujące mogą obsługiwać dane żądanie lub przekazywać je do następnego ogniwa łańcucha
Nowy wers Class monkeyhandler otwórz nawias okrągły abstracthandler zamknij nawias okrągły dwukropek
Nowy wers Def handle otwórz nawias okrągły self przecinek request dwukropek any zamknij nawias okrągły minus zamknij nawias ostrokątny es te er dwukropek
Nowy wers If request znak równości znak równości otwórz cudzysłów banan zamknij cudzysłów dwukropek
Nowy wers Return ef otwórz cudzysłów małpa dwukropek ten otwórz nawias klamrowy request zamknij nawias klamrowy będzie dla mnie wykrzyknik zamknij cudzysłów
Nowy wers Else dwukropek
Nowy wers Return super otwórz nawias okrągły zamknij nawias okrągły kropka handle otwórz nawias okrągły request zamknij nawias okrągły
Nowy wers Class squirrelhandler otwórz nawias okrągły abstracthandler zamknij nawias okrągły dwukropek
Nowy wers Def handle otwórz nawias okrągły self przecinek request dwukropek any zamknij nawias okrągły minus zamknij nawias ostrokątny es te er dwukropek
Nowy wers If request znak równości znak równości otwórz cudzysłów żołądź zamknij cudzysłów dwukropek
Nowy wers Return ef otwórz cudzysłów wiewiórka dwukropek ten otwórz nawias klamrowy request zamknij nawias klamrowy będzie dla mnie wykrzyknik zamknij cudzysłów
Nowy wers Else dwukropek
Nowy wers Return super otwórz zamknij nawias okrągły. Kropka handle otwórz nawias okrągły request zamknij nawias okrągły
Nowy wers Class doghandler otwórz nawias okrągły abstracthandler zamknij nawias okrągły dwukropek
Nowy wers Def handle otwórz nawias okrągły self przecinek request dwukropek any zamknij nawias okrągły minus zamknij nawias ostrokątny es te er dwukropek
Nowy wers If request znak równości znak równości otwórz cudzysłów pulpet zamknij cudzysłów dwukropek
Nowy wers Return ef otwórz cudzysłów pies dwukropek ten otwórz nawias klamrowy request zamknij nawias klamrowy będzie dla mnie wykrzyknik zamknij cudzysłów
Nowy wers Else dwukropek
Nowy wers Return super otwórz zamknij nawias okrągły. Kropka handle otwórz nawias okrągły request zamknij nawias okrągły
Objaśnienie szóste. Kod kliencki z reguły jest przystosowany do pracy z pojedynczym Obiektem Obsługującym i najczęściej nie zdaje sobie sprawy, że jest on częścią łańcucha
Nowy wers Def client podkreślnik code otwórz nawias okrągły handler dwukropek handler zamknij nawias okrągły minus zamknij nawias ostrokątny none dwukropek
Nowy wers For food in otwórz nawias kwadratowy otwórz cudzysłów orzech zamknij cudzysłów przecinek otwórz cudzysłów banan zamknij cudzysłów przecinek otwórz cudzysłów kubek kawy zamknij cudzysłów zamknij nawias kwadratowy dwukropek
Nowy wers Print otwórz nawias okrągły ef otwórz cudzysłów lewy ukośnik nclient dwukropek kto ma ochotę na otwórz nawias klamrowy food zamknij nawias klamrowy znak zapytania zamknij cudzysłów zamknij nawias okrągły
Nowy wers result znak równości handler kropka handle otwórz nawias okrągły food zamknij nawias okrągły
Nowy wers If result dwukropek
Nowy wers print otwórz nawias okrągły ef otwórz cudzysłów otwórz nawias klamrowy result zamknij nawias klamrowy zamknij cudzysłów przecinek end znak równości otwórz cudzysłów zamknij cudzysłów zamknij nawias okrągły
Nowy wers Else dwukropek
Nowy wers Print otwórz nawias ef otwórz cudzysłów otwórz nawias klamrowy food zamknij nawias klamrowy nie wzbudził niczyjego zainteresowania kropka zamknij cudzysłów Przecinek end znak równości otwórz cudzysłów zamknij cudzysłów zamknij nawias okrągły
Objaśnienie siódme. Tu stworzone zostały Konkretne Obiekty Obsługujące
Nowy wers If podkreślnik name podkreślnik znak równości znak równości otwórz cudzysłów podkreślnik main podkreślnikzamknij cudzysłów dwukropek
Nowy wers Monkey znak równości monkeyhandler otwórz zamknij nawias okrągły
Nowy wers Squirrel znak równości squirrelhandler otwórz zamknij nawias okrągły
Nowy wers Dog znak równości doghandler otwórz zamknij nawias okrągły
Objaśnienie ósme. Tu utworzone obiekty zostały połączone w łańcuch w kolejności dwukropek Małpa otwórz nawias ostrokątny Wiewiórka otwórz nawias ostrokątny Pies
Nowy wers Monkey kropka set podkreślnik next otwórz nawias okrągły squirrel zamknij nawias okrągły kropka set podkreślnik next otwórz nawias okrągły dog zamknij nawias okrągły
Nowy wers Print otwórz nawias okrągły otwórz cudzysłów łańcuch zobowiązań dwukropek małpa zamknij nawias ostrokątny wiewiórka zamknij nawias ostrokątny pies zamknij cudzysłów zamknij nawias okrągły
Objaśnienie dziewiąte. Kod kliencki powinien mieć możliwość wywołać żądanie dla każdego z Obiektów Obsługujących, nie tylko dla pierwszego w łańcuchu
Nowy wers Client podkreślnik otwórz nawias okrągły monkey zamknij nawias okrągły
Nowy wers Print otwórz nawias okrągły otwórz cudzysłów lewy ukośnik en zamknij cudzysłów zamknij nawias okrągły
Nowy wers Print otwórz nawias okrągły otwórz cudzysłów fragment łańcucha dwukropek wiewiórka zamknij nawias ostrokątny pies zamknij cudzysłów zamknij nawias okrągły
Nowy wers Client podkreślnik code otwórz nawias okrągły squirrel zamknij nawias okrągły
Wzorzec behawioralny trzy myślnik struktura i kod
Opis wzorca myślnik ćwiczenie pierwsze. Nagranie jest tożsame z treścią.
Kolejnym przykładem wzorca behawioralnego jest Łańcuch zobowiązań. Przeznaczeniem tego wzorca jest stworzenie mechanizmu przekazywania żądania między obiektami, z których każdy decyduje, czy wykonuje to żądanie, czy też przekazuje je dalej. Inne nazwy (ang. Chain of command, Chain of Responsibility). Motywacją jest zorganizowanie struktury kodu, w którym w wyniku wykonania pewnej operacji zrealizowanych musi zostać kilka mniejszych instrukcji w taki sposób, aby zapobiec powstawaniu wewnętrznych zawiłych zależności i zwiększyć możliwość reużycia kodu wykonującego pomniejsze instrukcje.
Opis wzorca myślnik ćwiczenie drugie. Nagranie jest tożsame z treścią.
Łańcuch zobowiązań można wykorzystać wszędzie tam, gdzie jedna operacja, np. logowanie do systemu, pociąga za sobą wiele mniejszych, a wykonanie głównej operacji jest sumą wykonanych pomniejszych operacji. W Łańcuchu Zobowiązań żądanie jest przekazywane z jednego obiektu do drugiego i jeśli w danym {obiekcie} żądanie może być wykonane, to tak się dzieje, a jeśli nie, to jest ono przekazywane dalej. W ten sposób jeden Łańcuch może przetwarzać tę samą operację na różne sposoby, zależnie od otrzymanych {danych} wejściowych, jak również przetwarzać różne operacje. Uczestnicy: Obiekt Obsługujący – czyli obiekt definiujący w sobie interfejs charakterystyczny dla wszystkich obiektów w Łańcuchu. Może on zawierać dwie metody: metodę do obsługi żądania oraz metodę do przekazywania żądania do kolejnego obiektu w łańcuchu. Bazowy Obiekt Obsługujący – czyli klasa, która może być wykorzystywana do tworzenia Obiektów Obsługujących. Zawiera ona w sobie te same {metody}, co Obiekt Obsługujący. Konkretny Obiekt Obsługujący – czyli Obiekt zawierający w sobie kod służący do obsługi żądań. Dodatkowo zawiera on w sobie logikę pozwalającą na określenie, czy żądanie ma zostać wykonane, czy przekazane dalej .Bazowy Obiekt Obsługujący może być wykorzystany do tworzenia Obiektów Obsługujących, co zapewnia ich kompatybilność z uwagi na posiadanie tego samego interfejsu. Gdy klient wysyła żądanie, trafia ono do kolejnych Obiektów Obsługujących, a związane z nimi Konkretne Obiekty Obsługujące podejmują decyzję, czy żądanie ma być wykonane, czy przekazane dalej. W ten sposób żądanie trafia finalnie do Obiektu, który może je obsłużyć, i klient otrzymuje odpowiedź zwrotną. Ten sam Łańcuch może obsługiwać różne rodzaje żądań i udzielać adekwatnych do nich odpowiedzi.
Opis wzorca myślnik ćwiczenie trzecie. Nagranie jest tożsame z treścią.
Łańcuch zobowiązań pozwala dodawać nowe funkcjonalności bez psucia istniejącego kodu. Umożliwia wykonywanie operacji w ustalonej wcześniej kolejności. Wadą takiego rozwiązania może być to, że niektóre żądania mogą nie zostać obsłużone. Na początku implementuje się interfejs do obsługi połączeń między Obiektami Obsługującymi. Następnie określa się, jakie żądania mają być obsługiwane przez każdy z obiektów. Jeśli planowo ma być stworzona większa liczba Obiektów Obsługujących, warto zastanowić się nad stworzeniem klasy do tworzenia tych obiektów – Bazowego Obiektu Obsługującego, co zaoszczędzi czas w pisaniu interfejsów dla każdego z obiektów i zmniejszy ilość powielonego kodu. Kolejnym etapem będzie stworzenie metod do obsługi żądań, metody przekazującej polecenie dalej oraz algorytmu decydującego, czy dane żądanie ma zostać wykonane, czy przekazane. Kod musi być elastyczny i pozwalać na wprowadzenie żądania do dowolnego ogniwa Łańcucha, jak również brać pod uwagę, że żądanie może zostać wykonane i zakończone, zanim dotrze do końca Łańcucha lub może przejść przez cały Łańcuch i nie zostać wykonane.
Opis wzorca myślnik ćwiczenie czwarte. Nagranie jest tożsame z treścią.
Łańcuch zobowiązań jest idealnym rozwiązaniem z jednej strony do wykorzystywania jednej struktury algorytmu do wykonywania różnych operacji, np. procedura logowania dla administratora może wyglądać zgoła inaczej niż dla zwykłego użytkownika, z drugiej strony może być wykorzystywana do przeprowadzania wieloetapowych operacji, gdzie każdy obiekt Łańcucha wykonuje inny etap operacji, a poszczególne etapy muszą być wykonywane w konkretnej kolejności, np. proces instalacji programu, gdzie zależnie od preferencji użytkownika poszczególne etapy mogą być dodatkowo pominięte. Wzorce: Łańcuch Zobowiązań, Mediator, Obserwator i Polecenie są stosowane do obsługi zależności i przepływu informacji między innymi obiektami, różni je jedynie ich rola i zastosowanie. Łańcuch zobowiązań często stosuje się wraz z Kompozytem, aby odsyłać odpowiedzi do nadrzędnych komponentów, co daje razem możliwość przemieszczania się danych zarówno w kierunku coraz prostszych elementów, jak również w kierunku odwrotnym.
Wzorzec architektoniczny jeden myślnik struktura i kod.
Widoczny jest schemat blokowy dotyczący zależności w strukturze MVC. Schemat zawiera sześć paneli. Trzy od góry, dwa od dołu po bokach, oraz jeden środkowy. Panele górne od lewej są podpisane model view oraz controller. Są połączone strzałkami od lewego elementu do prawego. Strzałka pomiędzy model a view zawiera nad sobą napis update view. Nad strzałką pomiędzy view a controller jest napis execute event. Pod panelem controller znajduje się concreate controller a na lewo od niego jest panel concreate model. Od concreate controller odchodzą dwie strzałki. Jedna do controller. Druga do concreate controller i jest podpisana update model. Środkowy panel to concreate view i od niego odchodzą dwie strzałki. Łączą się z view oraz concreate model i ta strzałka podpisana jest subject. Concreate model ma strzałkę skierowaną do panelu model.
Pierwszy wiersz. Przykładowy kod
Objaśnienie pierwsze. Import niezbędnych bibliotek
Nowy wers import re
Nowy wers import tkinter
Nowy wers From tkinter import ttk
Objaśnienie drugie. Tworzenie klasy modelu
Nowy wers Class model dwukropek
Nowy wers Def podkreślnik dolny init podkreślnik dolny otwórz nawias self przecinek email zamknij nawias okrągły dwukropek
Nowy wers Self kropka email znak równości email
Nowy wers Małpa property
Nowy wers Def email otwórz nawias okrągły self zamknij nawias okrągły dwukropek
Nowy wers Return self kropka podkreślnik dolny email
Nowy wers Małpa email kropka setter
Nowy wers def email otwórz nawias okrągły self kropka value zamknij nawias okrągły dwukropek
Objaśnienie trzecie. Sprawdzenie poprawność emaila
Nowy wers Pattern znak równości er apostrof lewy ukośnik be otwórz nawias kwadratowy a minus za minus zet zero minus dziewięć kropka podkreślnik dolny procent plus minus zamknij nawias kwadratowy plus znak małpy otwórz nawias kwadratowy a minus za minus zet zero minus dziewięć kropka minus zamknij nawias kwadratowy plus lewy ukośnik kropka otwórz nawias kwadratowy duże a minus duże zet kreska pionowa małe a minus małe zet zamknij nawias kwadratowy otwórz nawias klamrowy dwa przecinek zamknij nawias klamrowy lewy ukośnik be apostrof
Nowy wers If re kropka fullmach otwórz nawias okrągły pattern przecinek value zamknij nawias okrągły dwukropek
Nowy wers self kropka podkreślnik dolny email znak równości value
Nowy wers Else dwukropek
Nowy wers Raise valueerror otwórz nawias okrągły ef apostrof adres e myślnik mail jest nieprawidłowy wykrzyknik apostrof zamknij nawias okrągły
Objaśnienie czwarte. Zapisywanie emaila w pliku tekstowym
Nowy wers Def save otwórz nawias okrągły self zamknij nawias okrągły dwukropek
Nowy wers With open otwórz nawias okrągły apostrof lista podkreślnik dolny e myślnik mail kropka txt apostrof przecinek apostrof a apostrof zamknij nawias okrągły as ef dwukropek
Nowy wers Ef kropka write otwórz nawias okrągły self kropka email plus apostrof lewy ukośnik en apostrof zamknij nawias okrągły
Objaśnienie piąte. Tworzenie widżetów
Nowy wers Class view otwórz nawias okrągły te te ka kropka frame zamknij nawias okrągły dwukropek
Nowy wers def podkreślnik dolny init podkreślnik dolny otwórz nawias okrągły self przecinek parent zamknij nawias okrągły dwukropek
Nowy wers Super otwórz zamknij nawias okrągły kropka podkreślnik dolny init podkreślnik dolny otwórz nawias okrągły parent zamknij nawias okrągły
Objaśnienie szóste. Etykieta
Nowy wers Self kropka label znak równości te te ka kropka label otwórz nawias okrągły self przecinek text znak równości apostrof email dwukropek apostrof zamknij nawias okrągły
Nowy wers Self kropka label kropka grid otwórz nawias row znak równości jeden przecinek column znak równości zero zamknij nawias okrągły
Objaśnienie siódme. Wprowadzanie adresu e‑mail
Nowy wers Self kropka email podkreślnik dolny var znak równości tkinter kropka string var otwórz zamknij nawias okrągły
Nowy wers Self kropka email podkreśnik dolny entry znak równości te te ka kropka entry otwórz nawias okrągły self przecinek textvariable znak równości self kropka email podkreślnik dolny var przecinek width znak równości trzydzieści zamknij nawias okrągły
Nowy wers Self kropka email podkreślnik dolny entry kropka grid otwórz nawias okrągły row znak równości jeden przecinek column znak równości jeden przecinek sticky znak równości tkinter kropka nsew zamknij nawias okrągły
Objaśnienie ósme. Przycisk zapisu
Nowy wers Self kropka save podkreślnik dolny button znak równości te te ka kropka button otwórz nawias okrągły self przecinek text znak równości apostrof save apostrof przecinek command znak równości self kropka save podkreślnik dolny button podkreślnik dolny clicked zamknij nawias okrągły
Objaśnienie dziewiąte. Pole treści wiadomości
Nowy wers Self kropka save podkreślnik dolny button kropka grid otwórz nawias row znak równości jeden przecinek column znak równości trzy przecinek padx znak równości dziesięć zamknij nawias okrągły
Nowy wers Self kropka message podkreślnik dolny label znak równości te te ka kropka label otwórz nawias okrągły self przecinek text znak równości apostrof apostrof przecinek foreground znak równości apostrof red apostrof zamknij nawias okrągły
Nowy wers Self kropka message podkreślnik dolny label kropka grid otwórz nawias okrągły row znak równości dwa przecinek column znak równości jeden przecinek sticky znak równości tkinter kropka wu zamknij nawias okrągły
Objaśnienie dziesiąte. Przypisanie kontrolera
Nowy wers Self kropka controller znak równości none
Objaśnienie jedenaste. Metoda przypisująca Kontroler do Widoku
Nowy wers Def set podkreślnik dolny controller otwórz nawias self przecinek controller zamknij nawias okrągły dwukropek
Nowy wers Self kropka controller znak równości controller
Objaśnienie dwunaste. Obsługa kliknięcia przycisku
Nowy wers Def save podkreślnik dolny button podkreślnik dolny clicked otwórz nawias okrągły self zamknij nawias okrągły dwukropek
Nowy wers If self kropka controller dwukropek
Nowy wers Self kropka controller kropka save otwórz nawias okrągły self kropka email podkreślnik dolny var kropka get otwórz zamknij nawias okrągły zamknij nawias okrągły
Objaśnienie trzynaste. Wiadomość o błędzie
Nowy wers Def show podkreślnik dolny error otwórz nawias okrągły self przecinek message zamknij nawias okrągły dwukropek
Nowy wers Self kropka message podkreślnik dolny label otwórz nawias kwadratowy apostrof text apostrof zamknij nawias kwadratowy znak równości message
Nowy wers Self kropka message podkreślnik dolny label otwórz nawias kwadratowy apostrof foreground apostrof zamknij nawias kwadratowy znak równości apostrof red apostrof
Nowy wers Self kropka message podkreślnik dolny label kropka after otwórz nawias okrągły trzy zero zero zero przecinek self kropka hide podkreślnik dolny message zamknij nawias okrągły
Nowy wers Self kropka email podkreślnik dolny entry otwórz nawias kwadratowy apostrof foreground apostrof zamknij nawias kwadratowy znak równości apostrof red apostrof
Objaśnienie czternaste. Wiadomość o udanym wysłaniu wiadomości
Nowy wers Def show podkreślnik dolny success otwórz nawias okrągły self przecinek message zamknij nawias okrągły dwukropek
Nowy wers Self kropka message podkreślnik dolny label otwórz nawias kwadratowy apostrof text apostrof zamknij nawias kwadratowy znak równości message
Nowy wers Self kropka message podkreślnik dolny label otwórz nawias kwadratowy apostrof Foreground apostrof zamknij nawias kwadratowy znak równości apostrof green apostrof
Nowy wers Self kropka message podkreślnik dolny label kropka after otwórz nawias okrągły trzy zero zero zero przecinek self kropka hide podkreślnik dolny message zamknij nawias okrągły
Objaśnienie piętnaste. Zresetowanie formularza
Nowy wers Self kropka email podkreślnik dolny entry otwórz nawias kwadratowy apostrof foreground apostrof zamknij nawias kwadratowy znak równości apostrof black apostrof
Nowy wers Self kropka email podkreślnik dolny var kropka set otwórz nawias okrągły apostrof apostrof zamknij nawias okrągły
Objaśnienie szesnaste. Ukrycie wiadomości
Nowy wers Def hide podkreślnik dolny message otwórz nawias okrągły self zamknij nawias okrągły dwukropek
Nowy wers Self kropka message podkreślnik dolny label otwórz nawias kwadratowy apostrof text apostrof zamknij nawias kwadratowy znak równości apostrof apostrof
Objaśnienie siedemnaste. Tworzenie klasy Kontrolera
Nowy wers class controller dwukropek
Nowy wers Def podkreślnik dolny init podkreślnik dolny otwórz nawias okrągły self przecinek model przecinek view zamknij nawias okrągły dwukropek
Nowy wers Self kropka model znak równości model
Nowy wers Self kropka view znak równości view
Objaśnienie osiemnaste. Obsługa zapisu adresu email
Nowy wers Def save otwórz nawias okrągły self przecinek email zamknij nawias okrągły dwukropek
Nowy wers Try dwukropek
Objaśnienie dziewiętnaste. Zapisanie danych przez warstwę Modelu
Nowy wers Self kropka model kropka email znak równości email
Nowy wers Self kropka model kropka save otwórz zamknij nawias okrągły
Objaśnienie dwudzieste. Wyświetlenie pozytywnej wiadomości zwrotnej przez Widok
Nowy wers Self kropka view kropka show podkreślnik dolny success otwórz nawias okrągły ef apostrof the email otwórz nawias klamrowy email zamknij nawias klamrowy saved wykrzyknik apostrof zamknij nawias okrągły
Objaśnienie dwudzieste pierwsze. Wyświetlenie komunikatu o błędzie przez Widok
Nowy wers Except valueerror as error dwukropek
Nowy wers Self kropka view kropka show podkreślnik dolny error otwórz nawias okrągły error zamknij nawias okrągły
Objaśnienie dwudzieste drugie. Aktywacja aplikacji
Nowy wers Class app otwórz nawias okrągły tkinter kropka te ka zamknij nawias okrągły dwukropek
Nowy wers Def podkreślnik dolny init podkreślnik dolny otwórz nawias self zamknij nawias dwukropek
Nowy wers Super otwórz zamknij nawias okrągły kropka podkreślnik dolny init podkreślnik dolny otwórz zamknij nawias okrągły
Nowy wers Self kropka title otwórz nawias okrągły apostrof model widok kontroler apostrof zamknij nawias okrągły
Objaśnienie dwudzieste trzecie. Generowanie Modelu
Nowy wers Model znak równości model otwórz nawias okrągły apostrof anonim znak małpy email kropka com apostrof zamknij nawias okrągły
Objaśnienie dwudzieste czwarte. Generowanie Widoku
Nowy wers View znak równości view otwórz nawias self zamknij nawias okrągły
Nowy wers View kropka grid otwórz nawias okrągły row znak równości zero przecinek column znak równości zero przecinek padx znak równości dziesięć przecinek pady znak równości dziesięć zamknij nawias okrągły
Objaśnienie dwudzieste piąte. Generowanie kontrolera
Nowy wers Controler znak równości controller otwórz nawias okrągły model przecinek view zamknij nawias okrągły
Objaśnienie dwudzieste szóste. Przypisanie kontrolera do widoku
Nowy wers View kropka set podkreślnik dolny controller otwórz nawias okrągły controller zamknij nawias okrągły
Nowy wers If podkreślnik dolny name podkreślnik dolny znak równości znak równości apostrof podkreślnik dolny main podkreślnik dolny apostrof dwukropek
Nowy wers App znak równości app otwórz zamknij nawias okrągły
Nowy wers App kropka mainloop otwórz zamknij nawias okrągły
Wzorzec architektoniczny jeden myślnik struktura i kod.
Opis wzorca myślnik ćwiczenie pierwsze. Nagranie jest tożsame z treścią.
Model‑Widok‑Kontroler, który reprezentuje Wzorzec Architektoniczny wykorzystywany jest do zorganizowania struktury aplikacji posiadającej graficzny interfejs użytkownika (GUI) i podział tej struktury na 3 kooperujące ze sobą podstawowe sekcje, opisujące poszczególne elementy odpowiedzialne za wyświetlanie danych, zarządzanie aplikacją i przetwarzanie informacji. Inne nazwy (ang. Model‑View‑Controller), w skrócie MVC. Zastosowanie wzorca motywowane jest ustrukturyzowaniem kodu aplikacji względem przeznaczenia poszczególnych elementów kodu i powiązanie ich z jedną z trzech ról: definiowanie i zarządzanie danymi, wyświetlanie tych danych użytkownikowi oraz odbieranie i przesyłanie operacji wywoływanych przez użytkownika aplikacji.
Opis wzorca myślnik ćwiczenie drugie. Nagranie jest tożsame z treścią.
Wzorzec architektoniczny MVC jest wykorzystywany do organizowania struktury aplikacji i podziału całości kodu na 3 sekcje odpowiedzialne za różne segmenty, składające się na aplikację: Model – zawierający w sobie opis tego, jakie struktury danych są wykorzystywane w aplikacji, jak są zaprojektowane i jakie operacje można na nich wykonywać, Widok – określający, w jaki sposób te dane mają być wyświetlane użytkownikowi oraz Kontroler – definiujący, w jaki sposób aplikacja reaguje na zachowanie użytkownika i tworzy interfejs do komunikacji między aplikacją, a użytkownikiem. Jest to jeden z najczęściej stosowanych wzorców do tworzenia aplikacji posiadających graficzny interfejs użytkownika, m.in. aplikacje internetowe czy mobilne. Taka metoda organizowania kodu ułatwia zarządzanie nim, a tym samym obniża koszty jego utrzymywania, zwiększa jego czytelność oraz pozwala łatwiej rozbudowywać aplikację z uwagi na rozdzielenie kodu na {sekcje} o konkretnej roli i zastosowaniu. Uczestnicy: Model – zawiera on główną logikę biznesową, definiuje on struktury danych i metody ich modyfikacji. Zawiera w sobie wszystkie operacje, które są wykonywane „pod spodem” aplikacji, czyli te, których obecności i sposobu działania użytkownik nie musi być świadomy, czyli np. metodę wyliczania zdolności kredytowej na podstawie wprowadzonych {danych} w aplikacji bankowej. Widok – w warstwie tej zdefiniowane jest to, jak zawartość aplikacji wyświetlana jest użytkownikowi, określa ona między innymi, jaka jest struktura GUI, czy też obrabia dane pochodzące z Modelu do formy przyjaznej w odbiorze dla użytkownika .Kontroler – określa on, jak aplikacja zachowuje się, gdy użytkownik wykonuje pewne operacje, np. otwiera/zamyka kolejne okna, loguje się do aplikacji lub wprowadza pewne dane, czy też prosi o ich wyszukanie w bazie danych. Stanowi ona {interfejs} między użytkownikiem a aplikacją, a zatem czyni ona aplikację responsywną na działania użytkownika.
Opis wzorca myślnik ćwiczenie trzecie. Nagranie jest tożsame z treścią.
Użytkownik korzystając z aplikacji widzi kontent, za którego wyświetlanie odpowiada warstwa Widoku. Kiedy wykonuje on jakąś operację, na przykład wpisuje hasło w pole wyszukania, Kontroler odbiera tą operację i przekazuje informacje do {Modelu}, że konkretne dane muszą zostać wyszukane. Model daje odpowiedź do warstwy Widoku, w której obecne są dane wyszukiwane przez użytkownika lub informacja o ich braku. Warstwa Widoku, zależnie od otrzymanej informacji, może wyświetlić listę wyszukiwań z bazy lub informację zwrotną, że nie znaleziono żadnych informacji o oczekiwanych przez użytkownika atrybutach. Zatem warstwa Widoku może wpływać na to, jak wygląda zawartość strony zależnie od danych wejściowych pochodzących z Modelu. Dodatkowo, {Kontroler} może przekazywać informacje bezpośrednio do warstwy Widoku, jeśli operacja użytkownika nie jest związana z obsługą danych, np. zmiana rozmiaru czcionki czy koloru wyświetlania strony. W takiej sytuacji komunikacja Modelem może nie być wymagana. Podobnie Model może wysyłać informacje nie tylko do warstwy Widoku, ale również do warstwy Kontrolera, czy też do obu warstw jednocześnie – wszystko zależy od tego, czego wymaga operacja wywołana przez użytkownika. Zaletami wzorca MVC jest to, że rozdziela sekcje kodu odpowiedzialne za poszczególne elementy działania aplikacji i standaryzuje metody ich komunikacji. Ułatwia projektowanie aplikacji. Upraszcza rozbudowę i tworzenie nowych Widoków. Ogranicza ekspozycję kodu aplikacji dla kodu klienckiego. Niestety z uwagi na dodawanie kolejnego poziomu abstrakcji i dodatkowych interfejsów oraz sposobów interakcji, aplikacje zbudowane zgodnie ze wzorcem MVC mogą być bardzo złożone i trudne w debugowaniu. Widoki są zależne od Modeli, ale Modele nie muszą być zależne od Widoków, dlatego zmiany w Modelach muszą być przenoszone na wszystkie związane z nimi Widoki, aby zachować ich kompatybilność.
Opis wzorca myślnik ćwiczenie czwarte. Nagranie jest tożsame z treścią.
Implementację zaczyna się od ustalenia, jakie struktury danych będą stosowane w aplikacji i uwzględnia się je w warstwie Modelu. Zawiera się tu również metody, jakie mogą być na tych strukturach wykonywane. Następnie należy zastanowić się nad tym, w jaki sposób dane te mają być wyświetlane i zdefiniować to w warstwie Widoku. Można stworzyć także alternatywne Widoki, zależne od zawartości danych pochodzących z Modelu. Na końcu ustala się, w jaki sposób będą wyglądały interakcje między użytkownikiem a aplikacją i definiuje się ich przebieg w warstwie Kontrolera. Należy pamiętać także o stworzeniu odpowiednich instrukcji przekazujących zadania do warstw Modelu i Widoku. Można stworzyć także kolejne Widoki zależne od instrukcji otrzymywanych od użytkownika przez warstwę Kontrolera. Ten wzorzec architektoniczny wykorzystywany jest do tworzenia m.in. aplikacji internetowych, które nie wymagają automatycznego zarządzania stanem aplikacji (czyli aplikacja nie musi samoistnie się odświeżać). Mogą to być wszelkiego rodzaju {wyszukiwarki} internetowe czy też strony będące galeriami zdjęć (np. portfolio fotografów, bazy grafik. Wzorzec MVC jest wzorcem złożonym, który może być przedstawiony jako kombinacja innych wzorców projektowych: Kompozytu – wykorzystywanego w Widoku do zarządzania zagnieżdżonymi widokami, Obserwatora – stosowanego w Modelu i Widoku, powiadamia Widok o zmianie stanu aplikacji zarejestrowanej przez Model, np. w wyniku działań użytkownika oraz Strategii w Widoku i Kontrolerze – Widok przekazuje obsługę interakcji z użytkownikiem Kontrolerowi. Wzorzec MVC był podstawą dla stworzenia kolejnych wzorców architektonicznych, np. Model‑Widok‑Prezenter (MVP) i Model‑Widok‑Model Widoku (MVVM).
Struktura MVP
Widoczny jest schemat blokowy dotyczący zależności w strukturze MVP. W centrum na szczycie panel z napisem Interactor + Additem()Łączy się z położonym poniżej panelem z napisem Presenter + create View().Ten łączy się z położnym poniżej panelem z napisem Command +do Command() + undoCommand().Panel z napisem Presenter leżący w centrum schematu łączy się z położonym po prawej stronie panelem z napisem Selection State.Od lewej strony widoczna jest zależność z panelami Model i View.Ten ostatni jest w zależności z panelem położonym na szczycie opisanym jako Interactor.
Przykładowy kod
Objaśnienie 1: Jest to przykład aplikacji do odtwarzania piosenek
Objaśnienie 2: Import niezbędnych bibliotek
Nowy wers Import wx
Objaśnienie 3: Tworzenie klasy modelu
Nowy wers classAlbumModel nawias okrągły object koniec nawiasu dwukropek
Nowy wers delf podkreślnik init podkreślnik nawias okrągły self przecinek artist przecinek title koniec nawiasu dwukropek
Nowy wers self kropka artist znak równości artist
Nowy wers self kropka title znak równości title
Objaśnienie 4: Metoda do aktualizacji Modelu
Nowy wers delf updateModel nawias okrągły self koniec nawiasu dwukropek
Nowy wers self kropka selectedAlbum kropka title znak równości self kropka view kropka getTitle nawias okrągły koniec nawiasu
Nowy wers self kropka selectedAlbum kropka artist znak równości self kropka view kropka getArtist nawias okrągły koniec nawiasu
Nowy wers self kropka enableApplyAndCancelnawias okrągły False koniec nawiasu
Nowy wers self kropka loadViewFromModel nawias okrągły koniec nawiasu
Objaśnienie 5: Tworzenie klasy prezentera
Nowy wers class AlbumPresenter nawias okrągły object koniec nawiasu dwukropek
Nowy wers delf podkreślnik init podkreślnik nawias okrągły self przecinek albums przecinek view przecinek interactor koniec nawiasu dwukropek
Nowy wers self kropka albums znak równości albums
Nowy wers self kropka view znak równości view
Nowy wers interactor kropka Install nawias okrągły self przecinek view koniec nawiasu
Nowy wers self kropka isListening znak równości True
Nowy wers self kropka initView nawias okrągły koniec nawiasu
Nowy wers view kropka start nawias okrągły koniec nawiasu
Objaśnienie 6: Metoda ładowania widoku na podstawie danych z Modelu
Nowy wers def loadViewFromModel nawias okrągły self koniec nawiasu dwukropek
Nowy wers if self kropka isListening dwukropek
Nowy wers self kropka isListening znak równości False
Nowy wers self kropka refresh Album List nawias okrągły koniec nawiasu
Nowy wers self kropka view kropka title nawias okrągły self kropka selected Album kropka title koniec nawiasu
Nowy wers self kropka updateWindowTitle nawias okrągły koniec nawiasu
Nowy wers self kropka view kropka setArtlist nawias okrągły self kropka selected Album kropka artist koniec nawiasu
Nowy wers self kropka enable Apply And Cancel nawias okrągły False koniec nawiasu
Nowy wers self kropka isListening znak równości True
Objaśnienie 7: Metoda do odświeżania listy albumu
Nowy wers def refresh Album List nawias okrągły self koniec nawiasu dwukropek
Nowy wers current Album znak równości self kropka View kropka get SelectedAlbum nawias okrągły koniec nawiasu
Nowy wers self kropka view kropka setAlbums nawias okrągły self kropka albums koniec nawiasu
Nowy wers self kropka view kropka set SelectedAlbum nawias okrągły currentAlbum koniec nawiasu
Nowy wers self kropka selectedAlbum znak równości self kropka albums nawias kwadratowy current Album koniec nawiasu
Objaśnienie 8: Metoda do aktualizacji tytułu granego albumu
Nowy wers delf update WindowTitle nawias okrągły self koniec nawiasu dwukropek
Nowy wers self kropka view kropka set WindowTitle nawias okrągły cudzysłów Album dwukropek cudzysłów +self kropka view kropka title koniec nawiasu
Objaśnienie 9: Metoda do zatwierdzania zmian
Nowy wers delf enableApplyAndCancel nawias okrągły self przecinek enabled koniec nawiasu dwukropek
Nowy wers self kropka view kropka set ApplyEnabled nawias okrągły enabled koniec nawiasu
Nowy wers self kropka view kropka setCancelEnabled nawias okrągły enabled koniec nawiasu
Objaśnienie 10: Tworzenie Interaktora - klasy używanej przez Prezentera do obsługi zdarzeń
Nowy wers class AlbumInteractor nawias okrągły object koniec nawiasu dwukropek
Nowy wers delf instal nawias okrągły self przecinek presenter przecinek view koniec nawiasu dwukropek
Nowy wers self kropka presenter znak równości presenter
Nowy wers self kropka view znak równości view
Nowy wers view kropka albums kropka Bind nawias okrągły wx kropka EVT podkreślnik LISTBOX przecinek self kropka OnReloadNeeded koniec nawiasu
Nowy wers view kropka title kropka Bind nawias okrągły wx kropka EVT podkreślnik Text przecinek self kropka OnDataFieldUpdated koniec nawiasu
Nowy wers view kropka artist kropka Bind nawias okrągły wx kropka EVT podkreślnik Text przecinek self kropka OnDataFieldUpdated koniec nawiasu
Nowy wers view kropka apply kropka Bind nawias okrągły wz kropka EVT podkreślnik Button przecinek self kropka OnApply koniec nawiasu
Nowy wers view kropka cancel kropka Bind nawis okrągły wz kropka EVT podkreślnik Button przecinek self kropka OnReloadNeeded koniec nawiasu
Objaśnienie 11: Metoda wykonywana, gdy zmiany zostaną zatwierdzone przez użytkownika
Nowy wers def OnApply nawias okrągły self przecinek evt koniec nawiasu dwukropek
Nowy wers self kropka presenter kropka updateModel nawias okrągły koniec nawiasu
Objaśnienie 12: Metoda wykonywana, gdy wymagane jest ponowne załadowanie okienka
Nowy wers def OnReloadNeeded nawias okrągły self przecinek evt koniec nawiasu dwukropek
Nowy wers self kropka presenter kropka loadViewFromModel nawias okrągły koniec nawiasu
Objaśnienie 13: Metoda wykonywana, gdy zostaną wprowadzone zmiany w polach danych
Nowy wers def OnDataFieldUpdate nawias okrągły self przecinek evt koniec nawiasu dwukropek
Nowy wers self kropka presenter kropka dataFieldUpdated nawias okrągły koniec nawiasu
Objaśnienie 14: Tworzenie klasy widoku
Nowy wers class AlbumView nawias okrągły wx kropka Frame koniec nawiasu dwukropek
Nowy wers def podkreślnik kropka init podkreślnik nawias okrągły self koniec nawiasu dwukropek
Nowy wers self kropka app znak równości wx kropkaApp nawias okrągły zero koniec nawiasu
Nowy wers wx kropka Frame kropka podkreślnik init podkreślnik nawias okrągły self przecinek None koniec nawiasu
Nowy wers self kropka SetBackgroundColour nawias okrągły cudzysłów blue cudzysłów koniec nawiasu
Nowy wers def podkreślnik setTitle nawias okrągły self przecinek title koniec nawiasu dwukropek
Nowy wers self kropka podkreślnik title kropka SetValue nawias okrągły title koniec nawiasu
Nowy wers def podkreślnik getTitle nawias okrągły self koniec nawiasu dwukropek
Nowy wers return self kropka podkreślnik title kropka GetValue nawias okrągły koniec nawiasu
Nowy wers title znak równości property nawias okrągły podkreślnik getTitle przecinek podkreślnik setTitle koniec nawiasu
Wzorzec architektoniczny dwa myślnik struktura i kod
Opis wzorca myślnik ćwiczenie pierwsze. Nagranie jest tożsame z treścią.
Model‑Widok‑Prezenter to kolejny wzorzec architektoniczny, którego przeznaczeniem jest zorganizowanie struktury kodu aplikacji posiadającej graficzny interfejs użytkownika (GUI) i podział odpowiedzialności za poszczególne aspekty działania aplikacji na 3 główne sekcje, z których jedna z nich pełni rolę pośrednika między pozostałymi dwoma, jednej odpowiedzialnej za zarządzanie danymi i drugiej odpowiedzialnej za wyświetlanie widoków. Inne nazwy (ang. Model‑View‑Presenter, w skrócie MVP. Wzorzec ten motywowany jest stworzeniem zorganizowanej struktury kodu poprzez podział na sekcje odpowiedzialne za poszczególne elementy działania aplikacji posiadającej GUI, z których jedna pełni rolę pośrednika między pozostałymi dwoma, co ma na celu uproszczenie testowalności aplikacji, zwiększenie czytelności kodu, zmniejszenie kosztów jego utrzymania i łatwiejsze projektowanie oraz rozbudowywanie
Opis wzorca myślnik ćwiczenie drugie. Nagranie jest tożsame z treścią.
Wzorzec Model‑Widok‑Prezenter może być stosowany podobnie jak wzorzec Model‑Widok‑Kontroler, od którego pochodzi. Jednak w przypadku MVP wszystkie operacje przechodzą przez Prezentera, co ułatwia kontrolowanie przepływu danych, a tym samym przewidywalność działania kodu, testowalność aplikacji oraz jej rozbudowę z uwagi na zmniejszenie liczby niezbędnych do uwzględnienia interfejsów. Dzięki temu rozwiązaniu łatwiejsze jest też zarządzanie stanem aplikacji. Uczestnicy: Model – zawiera on główną logikę biznesową, definiuje struktury danych i metody ich modyfikacji. Jego rolą jest przetwarzanie danych i przekazywanie ich do warstwy Prezentera. Widok – w warstwie Widoku zdefiniowane jest to, jak zawartość aplikacji wyświetlana jest użytkownikowi. Przyjmuje dane pochodzące od Prezentera i wykorzystuje do wygenerowania widoku. Dodatkowo wykrywa aktywność użytkownika i informuje warstwę Prezentera o wywoływanych przez niego operacjach – jest więc jednym z czynników zapewniających aplikacji responsywność na działania użytkownika. Prezenter– warstwa pełniąca rolę pośrednika między Modelem a Widokiem, zawiera w sobie znaczącą ilość logiki biznesowej, pozwalającej z jednej strony na aktualizację danych w warstwie Modelu, a z drugiej strony na wywoływanie zmian w warstwie Widoku wynikających ze zmian w Modelu czy wskutek akcji użytkownika.
Opis wzorca myślnik ćwiczenie trzecie. Nagranie jest tożsame z treścią.
Warstwa Modelu, podobnie jak w przypadku wzorca MVC, zawiera w sobie większość logiki obejmującej obsługę danych. Odbiera polecenia z warstwy Prezentera, wykonuje odpowiednie operacje na danych (odczytuje, zmienia, usuwa i zapisuje je), a następnie odsyła w razie potrzeby informacje z powrotem do warstwy Prezentera. Warstwa Prezentera jest węzłem między Widokiem a {Modelem}. Przekazuje informacje z jednej warstwy do drugiej, a ponadto zawiera w sobie logikę pozwalającą na wprowadzanie zmian (aktualizacje) w obu pozostałych warstwach. Można powiedzieć, że warstwa ta koordynuje pracę całej aplikacji i zarządza przepływem informacji. Warstwa Widoku również bardzo przypomina swojego odpowiednika ze wzorca MVC, a zatem odpowiada za wyświetlanie kontentu aplikacji. Główna różnica między Widokami z wzorców MVC i MVP polega na tym, że w MVP Widok jest również odpowiedzialny za wykrywanie działań użytkownika i przekazywanie informacji o nich do {Prezentera}, który następnie koordynuje pracę kodu w celu przekazania ponownie do Widoku informacji o tym, jakie informacje w odpowiedzi ma otrzymać użytkownik. Zaletami tego wzorca jest to, że rozdziela ona sekcje kodu odpowiedzialne za poszczególne elementy działania aplikacji przy jednoczesnym ograniczeniu liczby połączeń między komponentami. Ułatwia projektowanie i rozbudowę aplikacji. Zwiększa przejrzystość i czytelność kodu. Ułatwia testowanie i debugowanie aplikacji. Wady: Dodanie dodatkowego poziomu abstrakcji może zwiększać złożoność kodu. Prezenter, z uwagi na swoją kluczową rolę, może stać się superklasą, skupiającą w sobie zbyt dużo kodu i odpowiedzialności. Złożoność klasy Prezentera powoduje, że śledzenie i aktualizowanie stanu aplikacji może być bardziej skomplikowane.
Opis wzorca myślnik ćwiczenie czwarte. Nagranie jest tożsame z treścią.
We wzorcu MVP bardzo ważne jest przemyślenie funkcjonalności aplikacji, aby wiedzieć, jakie elementy muszą znaleźć się w poszczególnych sekcjach (zwłaszcza w Prezenterze). Pracę można zacząć od stworzenia warstwy Modelu i scharakteryzowania struktur danych. Kolejnym etapem może być stworzenie warstwy Widoku, ustalenie, w jaki sposób dane będą prezentowane użytkownikowi. Na końcu tworzymy warstwę Prezentera, spajającą pozostałe dwie. Implementujemy metody odpowiedzialne za przenoszenie informacji między warstwami i aktualizowanie stanu aplikacji. Wzorzec MVP jest często wykorzystywany do tworzenia aplikacji mobilnych, np. dla systemu Android. Jest on też wykorzystywany m.in. we frameworku .NET do tworzenia aplikacji desktopowych oraz internetowych.
Model MVP jest ulepszoną wersją modelu MVC, który eliminuje jego wady związane z utrudnioną testowalnością czy znaczną liczbą interfejsów, będących skutkiem wzajemnego połączenia ze sobą wszystkich warstw wzorca. Z tego powodu mogą być one wykorzystywane wymiennie, zależnie od oczekiwań stawianych aplikacji Innym modelem o podobnej strukturze, lecz nieco innej dystrybucji odpowiedzialności między warstwami, jest wzorzec MVVM (Model‑Widok‑Model Widoku).
Struktura MVVM
Widoczny jest rysunek schematu struktury zależności MVVM. Składa się z trzech położonych szeregowo paneli. W środkowym panelu znajduje się napis -ViewModel, +State Notify nawias okrągły koniec nawiasu. Panel ten łączy się za pomocą strzałki z położonym po lewej panelem z napisem View pod nim + Update nawias okrągły koniec nawiasu oraz łączy się z położonym po prawej panelem z napisem Model +GetDatanawias okrągły koniec nawiasu. Poniżej panelu środkowego widoczny jest połączony strzałką panel z napisem Command + doCommand nawias okrągły koniec nawiasu + uncommand nawias okrągły koniec nawiasu.
Przykładowy kod
Objaśnienie: To jest przykładowy kod prezentujący wzorzec MVVM stworzony w języku JavaScript
Objaśnienie: Tworzenie warstwy modelu
Nowy wers var Model znak równości function nawias okrągły koniec nawiasu otwórz nawias klamrowy
Nowy wers var model znak równości function nawias okrągły koniec nawiasu otwórz nawias klamrowy
Nowy wers var podkreślnik model znak równości otwórz nawias klamrowy
Nowy wers apostrof first name apostrof dwukropek cudzysłów Jan cudzysłów przecinek
Nowy wers apostrof lastname apostrof dwukropek cudzysłów Kowalski cudzysłów
Nowy wers zamknij nawias klamrowy średnik
Nowy wers var listeners znak równości nawias kwadratowy koniec nawiasu średnik
Nowy wers this kropka subscribe znak równości function nawias okrągły listener koniec nawiasu otwórz nawias klamrowy
Nowy wers listeners kropka Push nawias okrągły listener koniec nawiasu średnik
Nowy wers koniec nawiasu klamrowego średnik
Nowy wers this kropka notify znak równości function nawias okrągły attribute podkreślnik name przecinek newValue koniec nawiasu otwórz nawias klamrowy
Nowy wers for nawias okrągły var i znak równości 0 średnik i znak mniejszości listeners kropka length średnik i plus plus koniec nawiasu otwórz nawias klamrowy
Nowy wers listeners nawias kwadratowy i koniec nawiasu nawias okrągły attribute podkreślnik name przecinek newValue koniec nawiasu średnik
Nowy wers zamknij nawias klamrowy
Nowy wers zamknij nawias klamrowy średnik
Nowy wers this kropka setCurrentValue znak równości function nawias okrągły attribute podkreślnik name koniec nawiasu otwórz nawias klamrowy
Nowy wers console kropka log nawias okrągły podkreślnik model nawias kwadratowy attribute podkreślnik name zamknij nawias średnik
Nowy wers return podkreślnik model nawias kwadratowy attribute podkreślnik name koniec nawiasu średnik
Nowy wers zamknij nawias klamrowy średnik
Nowy wers this kropka setCurrentValue znak równości function nawias okrągły attribute podkreślnik name przecinek value koniec nawiasu nawias klamrowy
Nowy wers podkreślnik model nawias kwadratowy attribute podkreślnik name koniec nawiasu znak równości value średnik
Nowy wers this kropka nofity nawias okrągły attribute podkreślnik name przecinek value koniec nawiasu średnik
Nowy wers zamknij nawias klamrowy średnik
Nowy wers zamknij nawias klamrowy średnik
Nowy wers return new model nawias okrągły koniec nawiasu średnik
Nowy wers zamknij nawias klamrowy średnik
Objaśnienie: Pierwszy z nich to kod HTML odpowiedzialny za wyświetlanie kontentu
Nowy wers znak mniejszości html znak większości
Nowy wers znak mniejszości head znak większości
Nowy wers znak mniejszości title znak większości przykładowy widok wzorca model‑Widok‑Model
Nowy wers Widoku znak mniejszości prawy ukośnik title znak większości
Nowy wers znak mniejszości prawy ukośnik head znak większości
Nowy wers znak mniejszości h1 znak większości Przykład MVVM znak mniejszości prawy ukośnik h1 znak większości
Nowy wers znak mniejszości body znak większości
Nowy wers znak mniejszości h3 znak większości Pierwsza linia formularza służy do podania imienia, druga linia formularza do podania nazwiska. Oba pola w tej samej linii są ze sobą sprzężone i reprezentowane przez ten sam model - zmiana wartości jednego z formularzy automatycznie zmienia wartość drugiego z nich - to doskonale pokazuje zarządzanie stanem aplikacji i aktualizację widoku w czasie rzeczywistym charakterystycznym dla wzorca MVVM znak mniejszości H3 znak większości
Nowy wers imię dwukropek znak mniejszości input type znak równości cudzysłów text cudzysłów name znak równości cudzysłów firstname cudzysłów id znak równości cudzysłów firstname cudzysłów znak większości
Nowy wers znak mniejszości input type znak równości cudzysłów text name znak równości cudzysłów firstname cudzysłów id znak równości podkreślnik label cudzysłów znak większości znak mniejszości br znak mniejszości
Nowy wers nazwisko dwukropek znak mniejszości input type znak równości cudzysłów text cudzysłów name znak równości cudzysłów lastname cudzysłów
Nowy wers id znak równości cudzysłów lastname cudzysłów znak mniejszości znak większości input type znak równości cudzysłów text cudzysłów name znak równości cudzysłów lastname cudzysłów
Nowy wers id znak równości cudzysłów lastname podkreślnik label cudzysłów znak większości znak mniejszości br znak większości
Nowy wers znak mniejszości prawy ukośnik body znak większości
Nowy wers znak mniejszości script type znak równości apostrof text ukośnik prawy jawascript apostrof src znak równości cudzysłów kropka ukośnik prawy model kropka js cudzysłów znak większości znak mniejszości ukośnik prawy script znak większości
Nowy wers znak mniejszości script type znak równości apostrof text ukośnik prawy jawascript apostrof src znak równości cudzysłów kropka ukośnik prawy viewmodel kropka js cudzysłów znak mniejszości znak większości ukośnik prawy script znak większości
Nowy wers znak mniejszości script type znak równości apostrof text ukośnik prawy jawascript apostrof src znak równości cudzysłów kropka ukośnik prawy view kropka js znak mniejszości znak większości ukośnik prawy script znak większości
Nowy wers znak mniejszości html znak większości
Objaśnienie: Drugi z nich to kod JavaScript umożliwiający komunikację Widoku z Modelem Widoku
Nowy wers var firstname podkreślnik input znak równości document kropka getElementByld nawias okrągły apostrof firstname apostrof koniec nawiasu średnik
Nowy wers var lastname podkreślnik input znak równości document kropka getElementByld nawias okrągły apostrof lastname apostrof koniec nawiasu średnik
Nowy wers var firstname podkreślnik label znak równości document kropka getElementByld nawias okrągły apostrof firstname podkreślnik label apostrof koniec nawiasu średnik
Nowy wers var lastname podkreślnik label znak równości document kropka getElementByld nawias okrągły apostrof lastname podkreślnik label apostrof koniec nawiasu średnik
Nowy wers var vm znak równości new ViewModel nawias okrągły Model koniec nawiasu średnik
Nowy wers vm kropka bind nawias okrągły firstname podkreślnik input przecinek apostrof firstname apostrof koniec nawiasu średnik
Nowy wers vm kropka bind nawias okrągły lastname podkreślnik input przecinek apostrof lastname apostrof koniec nawiasu średnik
Nowy wers vm kropka bind nawias okrągły firstname podkreślnik label przecinek apostrof firstname apostrof koniec nawiasu średnik
Nowy wers vm kropka bind nawias okrągły lastname podkreślnik label przecinek apostrof lastname apostrof koniec nawiasu średnik
Nowy wers var view model znak równości function nawias okrągły koniec nawiasu nawias klamrowy
Nowy wers var view model znak równości finction nawias okrągły model koniec nawiasu nawias klamrowy
Nowy wers this kropka bind znak równości function nawias okrągły view podkreślnik element przecinek model podkreślnik element koniec nawiasu nawias klamrowy
Nowy wers view podkreślnik element kropka value znak równości
Nowy wers model kropka getCurrentValue nawias okrągły model podkreślnik element koniec nawiasu średnik
Nowy wers model kropka subscribe nawias okrągły function nawias okrągły attribute podkreślnik name przecinek newValue koniec nawiasu nawias klamrowy
Nowy wers document kropka getElementsByName nawias okrągły attribute podkreślnik name koniec nawiasu kropka for Each nawias okrągły Functon nawias okrągły elem koniec nawiasu nawias klamrowy
Nowy wers elem kropka value znak równości new Value średnik
Nowy wers koniec nawiasu klamrowego koniec nawiasu okrągłego średnik
Nowy wers koniec nawiasu klamrowego koniec nawiasu okrągłego średnik
Nowy wers view podkreślnik element kropka addEventListener nawias okrągły apostrof input apostrof przecinek function nawias okrągły koniec nawiasu nawias klamrowy
Nowy wers model kropka setCurrentvalue nawias okrągły view podkreślnik element kropka name przecinek
Nowy wers view podkreślnik element kropka value koniec nawiasu średnik
Nowy wers koniec nawiasu klamrowego koniec nawiasu okrągłego średnik
Nowy wers koniec nawiasu klamrowego
Nowy wers koniec nawiasu klamrowego
Objaśnienie: Ostatni element to kod Modelu Widoku
Nowy wers return viewModel średnik
Nowy wers koniec nawiasu klamrowego średnik
Wzorzec architektoniczny trzy myślnik struktura i kod
Opis wzorca myślnik ćwiczenie pierwsze. Nagranie jest tożsame z treścią.
Model‑Widok‑Model Widoku to również wzorzec architektoniczny. Jego przeznaczeniem jest tworzenie aplikacji posiadających GUI. Jest on wzorcem wykorzystywanym do tworzenia aplikacji, w których interfejs użytkownika jest bardzo zaawansowany i charakteryzuje się dużą złożonością. Inne nazwy (ang. Model‑View‑ViewModel, MVVM )Motywacją do jego powstania było stworzenie zorganizowanej struktury dla aplikacji posiadającej graficzny interfejs użytkownika (GUI), w której logika biznesowa jest całkowicie oddzielona od logiki prezentacji i obsługi interfejsu użytkownika, a sam interfejs użytkownika charakteryzuje się dużą złożonością i skomplikowaniem.
Opis wzorca myślnik ćwiczenie drugie. Nagranie jest tożsame z treścią.
Wzorzec Model‑Widok‑Model Widoku wykorzystuje WPF (Windows Presentation Foundation), czyli silnik graficzny, który pozwala na zastosowanie m.in. grafik wektorowych, modeli 3D i wielu innych multimediów. Z tego powodu stosowany jest do wszelkiego rodzaju aplikacji, gdzie GUI pełni kluczową rolę w funkcjonowaniu aplikacji, jak np. w grach przeglądarkowych czy platformach e‑learningowych. Uczestnicy: Model – zawiera całą logikę biznesową, definiuje też struktury danych wykorzystywanych w aplikacji i metody ich zmian. Nie ma bezpośredniego kontaktu z warstwą Widoku, dlatego przekazuje wszystkie informacje do Modelu Widoku. Widok – pełni rolę interfejsu użytkownika aplikacji. Rejestruje działania użytkownika i przekazuje do warstwy Modelu Widoku informację o konieczności zmiany danych. Razem z Modelem Widoku odpowiada za warstwę prezentacji całego programu. Model Widoku – jest to warstwa, która odpowiada za logikę wyświetlania Widoku. Wykonuje operacje związane z obróbką danych i przetwarzaniem informacji dla warstwy Widoku. Dodatkowo przekazuje informacje o konieczności przetworzenia informacji do warstwy Modelu i odbiera od niej odpowiedzi zwrotne.
Opis wzorca myślnik ćwiczenie trzecie. Nagranie jest tożsame z treścią.
Model, jako warstwa zawierająca logikę biznesową, jest połączona z warstwą Modelu Widoku, która przesyła informacje o konieczności wykonania jakiejś operacji biznesowej, a następnie odbiera od niej odpowiedź, którą może być jakiś pakiet {danych}. Jedną z głównych ról warstwy Modelu Widoku jest takie przetworzenie danych, aby warstwa Widoku mogła użyć ich od razu do wyrenderowania widoku interfejsu. Warstwa Widoku wykorzystuje te informacje, aby stworzyć interfejs graficzny. Jeśli operacja użytkownika nie wymaga przetwarzania danych biznesowych, tylko polega na przykład na przesuwaniu elementów po ekranie, zmiany koloru ekranu, itp., to warstwa Widoku wykonuje takie operacje samodzielnie, bez komunikacji z pozostałymi {warstwami}. Dodatkowo, warstwa Modelu Widoku nie pełni żadnej roli kontrolnej nad warstwą Widoku, nie może ona również w pełni kontrolować jej stanu, gdyż nie ma do niej żadnych referencji – przekazuje jej jedynie obrobione dane z warstwy Modelu. Dodatkowo Model Widoku może obsługiwać kilka Widoków. Separacja logiki biznesowej od warstwy prezentacji pozwala utrzymać porządek kodu i ułatwia jego utrzymywanie. Rozdzielenie logiki prezentacji od interfejsu użytkownika sprawia, że kod jest bardziej hermetyczny, a zależności między logiką a interfejsem są ograniczone. Przenoszenie informacji w obu kierunkach przez warstwę Modelu Widoku ułatwia debugowanie i testowanie aplikacji. Wadami takiego rozwiązania jest to, że dodanie dodatkowego poziomu abstrakcji może zwiększać złożoność kodu. Dodatkowo brak kontroli warstwy Modelu Widoku nad Widokiem może znacząco utrudniać wdrażanie pewnych funkcji, co komplikuje kod.
Opis wzorca myślnik ćwiczenie czwarte. Nagranie jest tożsame z treścią.
Podczas Implementacji warto zacząć od wprowadzenia logiki biznesowej i opisania struktur danych w warstwie Modelu. Następnym krokiem jest stworzenie warstwy Modelu Widoku, która będzie miała za zadanie przetwarzać informacje pochodzące z Modelu i przekazywać je dalej, do warstwy Widoku. Na końcu zajmij się tworzeniem interfejsu i scharakteryzowaniem metod interakcji między użytkownikiem a aplikacją w warstwie Widoku. Model MVVM jest używany zarówno do tworzenia aplikacji desktopowych, jak i internetowych, które charakteryzują dynamiczne interfejsy, jak również daje możliwość pewnej kontroli stanu aplikacji. Popularnymi bibliotekami i frameworkami wykorzystującymi wzorzec MVVM są JavaScriptowe Vue.js oraz ReactModel MVVM jest modyfikacją modelu MVC, przeznaczoną do tworzenia bardziej wymagających GUI oraz wprowadzających kilka uproszczeń związanych np. z testowalnością aplikacji. Innym modelem o podobnej strukturze, lecz nieco innej dystrybucji odpowiedzialności między warstwami i innych zastosowaniach, jest wzorzec MVP Model‑Widok‑Prezenter.
Spis pojęć
abstrakcjaabstrakcja
bibliotekabiblioteka
frameworkframework
funkcjafunkcja
implementacjaimplementacja
interfejsinterfejs
klasaklasa
logikalogika
metodametoda
obiektobiekt
Powrót do spisu treściPowrót do spisu treści