750 likes | 923 Views
Techniki projektowania – wzorce projektowe. PROJEKTOWANIE. Stan „posiadania” Przypadki użycia Model dziedziny Operacje systemowe Kontrakty dla operacji systemowych Problemy do rozwiązania Zakres odpowiedzialności poszczególnych klas?
E N D
PROJEKTOWANIE Stan „posiadania” • Przypadki użycia • Model dziedziny • Operacje systemowe • Kontrakty dla operacji systemowych Problemy do rozwiązania • Zakres odpowiedzialności poszczególnych klas? • Współdziałanie (kooperacja) obiektów w celu realizacji warunków zapisanych w kontrakcie 2
DOMAIN DRIVEN DESIGN (W SKRÓCIE DDD) • Domain Driven Designjest koncepcją projektowania systemów informatycznych, w której kluczową rolę odgrywa model dziedziny • Autorem DDD jest Eric Evans (Domain-Driven Design: Tackling Complexity in the Heart of Software, 2003) • W literaturze polskiej funkcjonują następujące tłumaczenia terminu DDD: • Projektowanie Zorientowane na Dziedzinę • Projektowanie Sterowane Modelem/Dziedziną • Koncepcja DDD to zbiór podstawowych zasad, wzorców oraz sprawdzonych praktyk ułatwiających projektowanie systemu • Systemy projektowane zgodnie z duchem DDD mają strukturę warstwową 3
PODSTAWOWE ELEMENTY DDD Encja (ang. Entity) Wartość (ang. Value Object) Serwis (ang. Service) Agregat (ang. Aggregate) Repozytorium (ang. Repository) Fabryka (ang. Factory) 4
OBIEKTY ENCYJNE I WARTOŚCI Entity – obiekty identyfikowalne • Tożsamość obiektu jest niezależna od jego stanu • Obiekt może zmienić stan i nadal będzie postrzegany jako ten sam obiekt • Przykłady: Osoba, Rachunek, Produkt Value Object – obiekty nieidentyfikowalne • Tożsamość obiektu stanowi jego stan • Obiekt po zmianie stanu jest postrzegany już jako inny obiekt • Przykłady: Pieniądz, Data, Punkt,Adres 5
AGREGAT – CO TO JEST? Agregat to podzbiór elementów modelu, który stanowi spójną całość w ramach której spełniane są warunki integralności danych W każdym agregacie istnieje dokładnie jeden element zwany korzeniem i pozostałe elementami zwane wewnętrznymi korzeń agregatu agregat 6 element wewnętrzny
AGREGAT – HERMETYZACJA Korzeń agregatu jest dostępny dla świata zewnętrznego, tzn. obiekty spoza agregatu mogą się do niego bezpośrednio odwoływać Obiekty wewnętrzne nie są bezpośrednio dostępne dla świata zewnętrznego Obiekty wewnętrzne mogą się jednak odwoływać do innych korzeni agregatów Dostęp do obiektów wewnętrznych jest możliwy tylko poprzez korzeń agregatu Agregaty nie mogą współdzielić elementów wewnętrznych – dany element (obiekt) może być częścią tylko jednego agregatu 7
AGREGAT – KORZYŚCI • Agregat ułatwia zarządzanie cyklem życia obiektów – agregaty są zapisywane, odtwarzane i usuwane jako całość, co sprzyja utrzymaniu integralności danych • Agregat chroni swoje obiekty wewnętrzne – żaden obiekt ze świata zewnętrznego nie może wykonać operacji na obiektach wewnętrznych agregatu inaczej niż za pośrednictwem korzenia, dzięki temu istniej możliwość kontroli działań wykonywanych na obiektach wewnętrznych, co również sprzyja utrzymaniu integralności danych 8
IDENTYFIKACJA AGREGATÓW Jeżeli obiekty klasy A mogą wystąpić samodzielnie (tj. bez związku z innymi obiektami), to obiekty klasy A powinny być korzeniami agregatu Jeżeli obiekty klasy B posiadają powiązania tylko z obiektami klasy A, które to są korzeniami agregatu i ponadto obiekty klasy B nie mogą występować samodzielnie (bez powiązania z jakimś obiektem klasy A), to obiekty klasy B powinny wchodzić w skład agregatu zbudowanego wokół obiektów klasy A 9
AGREGAT – PRZYKŁAD Klasy Wydarzenie i Osoba są jedynymi klasami, których obiekty mogą występować samodzielnie → Obiekty klas Wydarzenie i Osoba są korzeniami agregatów Obiekty klasy Alarm mogą być powiązane tylko z obiektami klasy Wydarzenie, nie mogą też pojawić się samodzielnie → obiekty klasy Alarm są elementami wewnętrznymi w agregacie Wydarzenie Obiekty klasy Adres mogą być powiązane tylko z obiektami klasy Osoba, nie mogą też pojawić się samodzielnie → obiekty klasy Adres są elementami wewnętrznymi w agregacie Osoba Obiekty klasy Uczestnictwo bez związków z obiektami klas Osoba i Wydarzenie nic nie znaczą, powinny być zarządzane przez jeden z wcześniej zidentyfikowanych agregatów → obiekty klasy Uczestnictwo będą elementami wewnętrzymi w agregacie Wydarzenie korzeń agregat 10 korzeń
PROBLEM Z DOSTĘPEM DO OBIEKTÓW BIZNESOWYCH • Jeśli klient chce wykonać pewną operację na jednym z obiektów biznesowych, to możliwe są następujące scenariusze: • Jeśli obiekt biznesowy nie istnieje, klient tworzy taki obiekt i wykonuje na nim operację • Jeśli obiekt biznesowy istnieje, klient uzyskuje dostęp do interesującego obiektu i wykonuje na nim operację • Scenariusz 1 nie stwarza większych problemów w realizacji, pod warunkiem jednak że klient posiada kompletne dane potrzebne do utworzenia obiektu biznesowego • Scenariusz 2 może stanowić problem, w sytuacji dużej liczby obiektów biznesowych • Rozwiązanie dla scenariusza 2 polegające na przechowywaniu wszystkich obiektów biznesowych przez klienta zwiększa niestety liczbę powiązań pomiędzy warstwami i tym samym poziom zależności miedzy warstwami 11
PROBLEM Z DOSTĘPEM DO OBIEKTÓW BIZNESOWYCH (2) W wielu systemach informatycznych wymaga się zapisywania stanu systemu w bazie danych po wykonaniu ciągu operacji systemowych i odtworzenia tegoż stanu w przypadku awarii lub w chwili uruchomienia systemu od nowa W wielu systemach informatycznych liczba obiektów biznesowych jest na tyle duża, że nie jest możliwe ich jednoczesne przetwarzanie w pamięci operacyjnej – potrzebna jest baza danych, w której te obiekty są przechowywane i udostępnianie na żądanie Wszystkie powyższe problemy mogą być efektywnie rozwiązane poprzez wprowadzenie repozytoriów obiektów biznesowych 12
REPOZYTORIUM Wzorzec repozytorium umożliwia dostęp do puli obiektów biznesowych ukrywając przed klientem wszelkie mechanizmy dostępu do bazy danych Z punktu widzenia klienta repozytorium może być traktowane jako kolekcja obiektów biznesowych Repozytorium udostępnia swoim klientom operacje zapisu, odczytu, aktualizacji, usuwania oraz wyszukiwania obiektów biznesowych Koncepcja DDD zaleca utworzenie jednego repozytorium dla każdego agregatu 13
REPOZYTORIUM – PRZYKŁAD • Repozytorium wydarzeń – obsługuje agregat Wydarzenie, który składa się z następujących klas: • Wydarzenie • Alarm • Uczestnictwo • Repozytorium osób – obsługuje agregat Osoba, który składa się z następujących klas: • Osoba • Adres warstwa logiki biznesowej warstwa infrastruktury 14
SERWIS W myśl koncepcji DDD serwisy to specjalizowane klasy przeznaczone do wykonywania operacji biznesowych, których nie można przypisać do jednego obiektu biznesowego W szerszym znaczeniu serwisem jest również klasa odpowiedzialna za koordynacje działań związanych z wykonywaniem operacji systemowych w ramach jednego przypadku użycia Serwisy nie posiadają wewnętrznego stanu – zwykle tworzone są na potrzeby konkretnego zadania i po jego wykonaniu są usuwane Serwis jest obiektem rozpoczynającym obsługę operacji systemowej 15
SERWISY – PRZYKŁAD • Serwis Wydarzeń – odpowiada za zarządzanie wykonywaniem operacji systemowych związanych wydarzeniami, np.: • UtworzWydarzenie() • DodajAlarm() • DodajUczestnika() • Serwis Osób – odpowiada za zarządzanie wykonywaniem operacji systemowych związanych osobami, np. : • UtworzOsobe() • UsunOsobe() warstwa aplikacji warstwa logiki biznesowej warstwa infrastruktury 16
Opis dziedziny problemu System jest przeznaczony do obsługi procesu sprzedaży. Podstawowa funkcjonalność systemu obejmuje takie czynności jak: wprowadzanie kodów towarów kupowanych przez klienta, obliczanie kwoty do zapłaty, obsługa wszystkich rodzajów płatności (m.in. gotówka, karta kredytowa). System powinien współpracować z systemami finansowo-księgowymi. Ze względu na zmieniające się przepisy podatkowe system powinien umożliwiać zmianę reguł obliczania podatków. System musi ponadto utrzymywać aktualną bazę dostępnych towarów Techniki projektowania - wzorce GRASP Przykład: Kasa fiskalna
Store – reprezentuje sklep. Sklep opisany jest atrybutami oznaczającymi jego nazwę i fizyczną lokalizację (name, address) Register – reprezentuje kasę fiskalną, na której dokonywane są transakcje Cashier – reprezentuje osobę obsługującą kasę fiskalną Customer – reprezentuje klienta dokonującego zakupu Techniki projektowania - wzorce GRASP Identyfikacja klas konceptualnych (1)
ProductCatalog – reprezentuje katalog produktów oferowanych do sprzedaży • ProductDescription – reprezentuje opis produktu. Zawiera takie atrybuty jak description (opis produktu) oraz price (cena) • Payment – reprezentuje płatność . Zawiera atrybut amountTendered do przechowywania zapłaconej kwoty Techniki projektowania - wzorce GRASP Identyfikacja klas konceptualnych (2)
Sale – reprezentuje bieżącą sprzedaż (i jednocześnie dokument sprzedaży). Zawiera atrybut date do przechowywania daty transakcji oraz atrybut total do przechowywania całkowitej kwoty do zapłaty SaleLineItem – reprezentuje jedną pozycję na dokumencie sprzedaży. Zawiera atrybut quantity do przechowywania ilości zakupionego towaru Techniki projektowania - wzorce GRASP Identyfikacja klas konceptualnych (3)
Techniki projektowania - wzorce GRASP Model dziedziny
Przypadek użycia: Obsługa sprzedaży Wyzwalacz: Klient przychodzi do kasy z produktami, które zamierza kupić Scenariusz główny: Kasjer rozpoczyna nowy proces sprzedaży Kasjer skanuje kod towaru System rejestruje pozycje sprzedaży, wyświetla opis produktu, cenę oraz oblicza kwotę do zapłaty Kroki 2-3 są powtarzane dla wszystkich produktów System wyświetla kwotę do zapłaty Kasjer informuje klienta o kwocie do zapłaty Klient za pośrednictwem kasjera dokonuje płatności System rejestruje płatność Techniki projektowania - wzorce GRASP Przypadek użycia
Techniki projektowania - wzorce GRASP Diagram sekwencji systemowych Główny scenariusz: Kasjer rozpoczyna nowy proces sprzedaży Kasjer skanuje kod towaru System rejestruje pozycje sprzedaży, wyświetla opis produktu, cenę oraz oblicza kwotę do zapłaty Kroki 2-3 są powtarzane dla wszystkich produktów System wyświetla kwotę do zapłaty Kasjer informuje klienta o kwocie do zapłaty Klient za pośrednictwem kasjera dokonuje płatności System rejestruje płatność
Operacja: MakeNewSale() Warunki początkowe: Istnieje obiekt r klasy Register Warunki końcowe: Utworzono obiekt s klasy Sale Atrybutowi s.dateTime przypisano bieżącą datę i czas Utworzono związek pomiędzy obiektem s a obiektem r Techniki projektowania - wzorce GRASP Kontrakty dla operacji systemowych (1)
Operacja: EnterItem(itemId, quantity) Warunki początkowe: • Istnieje obiekt s klasy Sale oraz obiekt pd klasy ProductDescription Warunki końcowe: • Utworzono obiekt sli klasy SaleLineItem • Atrybutowi sli.quantity przypisano wartość argumentu quantity • Utworzono związek pomiędzy obiektem sli a obiektem s • Utworzono związek pomiędzy obiektem sli a obiektem pd Techniki projektowania - wzorce GRASP Kontrakty dla operacji systemowych (2)
Operacja: EndSale() Warunki początkowe: Istnieje obiekt s klasy Sale Warunki końcowe: Atrybutowi s.isComplete przypisano wartość true Techniki projektowania - wzorce GRASP Kontrakty dla operacji systemowych (3)
Operacja: MakePayment(amount) Warunki początkowe: Istnieje obiekt s klasy Sale Warunki końcowe: Utworzono obiekt p klasy Payment Atrybutowi p.amountTendered przypisano wartość argumentu amount Utworzono związek pomiędzy obiektem p a obiektem s Techniki projektowania - wzorce GRASP Kontrakty dla operacji systemowych (4)
Operacja systemowa trafia do jednego z serwisów Do zadań serwisu należy pobranie z repozytorium obiektu biznesowego, którego dotyczy operacja oraz delegowanie wykonania operacji do tegoż obiektu Jeśli operacja nie może być przypisana do jednego obiektu biznesowego, wówczas serwis wykonuje wszystkie czynności wymagane przez operacje Projektowanie interakcji wg DDD – wskazówki
Diagram sekwencji dla operacji DodajUczestnika() Serwis Wydarzeń znajduje obiekt Wydarzenie w Repozytorium Wydarzeń oraz obiekt Osoba w Repozytorium Osób Wydarzenie tworzy obiekt klasy Uczestnik i dodaje go do swojej listy (DodajUczestnika) Komunikat systemowy DodajUczestnika() jest odbierany przez obiekt Serwis Wydarzeń Serwis Wydarzeń deleguje wykonanie operacji dodania uczestnika do obiektu Wydarzenie przekazując mu obiekt Osoba
Stan wyjściowy:Operacje systemowe są specyfikacją zachowania systemu widzianego z poziomu jego klienta (np. interfejsu użytkownika). Kontrakty dla operacji systemowych opisują stan systemu przed i po wykonaniu operacji systemowej Problem do rozwiązania:Jak przypisać odpowiedzialności do poszczególnych klas i zaprojektować interakcje obiektów, aby zrealizować warunki zapisane w kontrakcie? Techniki projektowania - wzorce GRASP Projektowanie
GRASP - General Resposibility Assignment Software Patterns • GRASP to zbiór kilku wzorców projektowania obiektowego związanych z przypisywaniem odpowiedzialności do klas. • Autorem wzorców GRASP jest Craig Larman • Każdy ze wzorców GRASP to rodzaj zalecenia projektowego, którego uwzględnienie z reguły prowadzi do lepszego rozwiązanie problemu Techniki projektowania - wzorce GRASP Wzorce GRASP
Ekspert (ang. Expert) Kreator (ang. Creator) Kontroler (ang. Contoller) Luźne sprzężenie (ang. Low Coupling) Wysoka spójność (ang. High Cohesion) Pure Fabrication Polimorfizm (ang. Polimorphism) Techniki projektowania - wzorce GRASP Wzorce GRASP
Problem: Która klasa powinna być odpowiedzialna za tworzenie nowych instancji danej klasy? • Rozwiązanie: Przypisz klasie B odpowiedzialność tworzenia nowych instancji klasy A, jeśli zachodzi jeden lub kilka z poniższych warunków: • Klasa B zawiera (agreguje) obiekty klasy A • Klasa B rejestruje obiekty klasy A • Klasa B intensywnie używa obiekty klasy A • Klasa B posiada dane niezbędne do zainicjalizowania obiektów klasy A Techniki projektowania - wzorce GRASP Wzorce GRASP-Kreator
Im więcej z powyższych punktów jest spełnione, tym mocniejsze jest uzasadnienie dla wyboru klasy B jako kreatora obiektów klasy A W sytuacji, gdy kilka klas kandyduje do bycia kreatorem obiektów klasy A, wówczas wybieramy te klasę, która spełnia najwięcej z powyższych warunków Techniki projektowania - wzorce GRASP Wzorce GRASP–Kreator
Techniki projektowania - wzorce GRASP Kreator - przykład • Problem: Która klasa powinna być odpowiedzialna za utworzenie obiektu typu SalesLineItem? • Kandydaci: • Sale • zawiera obiekty typu SalesLineItems • używa obiekty typu SalesLineItems • posiada niezbędne dane (quantity) do zainicjowania obiekt typu SalesLineItems • ProductDescription - jest opisem dla obiektów SalesLineItems model dziedziny (fragment )
Techniki projektowania - wzorce GRASP Kreator - przykład Rozwiązanie: Na podstawie wzorca Kreator obiekty klasy SalesLineItem powinny być tworzone przez obiekt klasy Sale
Techniki projektowania - wzorce GRASP Kreator - przykład • Elementy modelu projektowego: • kierunek nawigacji od Register do Sale • atrybut currentSale w klasie Register – realizacja związku Register – Sale • kierunek nawigacji od Sale do SalesLineItem • atrybut lineItems w klasie Sale – realizacja związku Sale - SalesLineItems Model projektowy (fragment)
Problem: Jak brzmi najbardziej ogólna zasada przypisywania odpowiedzialności? Której klasie przypisać daną odpowiedzialność? • Rozwiązanie: Przypisz odpowiedzialność klasie, która ma niezbędne informacje, aby ją zrealizować Techniki projektowania - wzorce GRASP Wzorce GRASP- Ekspert
Wzorzec Ekspert jest jedną z elementarnych zasad projektowania obiektowego Mimo iż powyższa zasada brzmi jak coś oczywistego, jej zastosowanie może nieraz nastręczać trudności Potencjalne problemy z poprawnym stosowaniem wzorca ekspert wynikają najczęściej z rozproszenia informacji po wielu różnych klasach Techniki projektowania - wzorce GRASP Wzorce GRASP- Ekspert
Do poprawnego zastosowania wzorca Ekspert w przypadku rozproszenia informacji konieczny jest podział odpowiedzialności pomiędzy wszystkie klasy posiadające częściowe informacje Każda z klas posiadających częściowe informacje jest tzw. częściowym ekspertem Innym problemem związanym ze wzorcem Ekspert jest naturalna skłonność do przypisywania odpowiedzialności kierując się zasadą, by klasy systemu informatycznego zachowywały się podobnie jak klasy w świecie rzeczywistym, co nie zawsze jest dobrym rozwiązaniem Techniki projektowania - wzorce GRASP Wzorce GRASP- Ekspert
Techniki projektowania - wzorce GRASP Ekspert - przykład • Problem: Która klasa powinna być odpowiedzialna za obliczenie kwoty do zapłaty • Kandydaci: • Sale – zawiera atrybut total do przechowywania kwoty do zapłaty • SalesLineItem – zawiera atrybut quantity niezbędny do obliczenia kwoty do zapłaty za każdy z produktów z osobna • ProductDescription – zawiera atrybut price z bieżącą ceną każdego z produktów model dziedziny (fragment )
Techniki projektowania - wzorce GRASP Ekspert - przykład • Rozwiązanie: • Klasy SalesLineItem i ProductDescription są częściowymi ekspertami - zawierają jedynie cześć informacji niezbędnej do obliczenia całkowitej kwoty do zapłaty • Do obliczenia całkowitej kwoty do zapłaty należy zaprojektować odpowiednią interakcję pomiędzy wszystkimi klasami posiadającymi cząstkową informację
Techniki projektowania - wzorce GRASP Ekspert - przykład • Elementy modelu projektowego: • kierunek nawigacji od SalesLineItem do ProductDescription • atrybut description w klasie SalesLineItem – realizacja związku SalesLineItem - ProductDescription • Operacja GetTotal() w klasie Sale • Operacja GetSubtotal() w klasie SalesLineItem • Operacja GetPrice() w klasie ProductDescription Model projektowy (fragment)
Problem: Która klasa spoza interfejsu użytkownika powinna jako pierwsza obsługiwać operacje systemową? • Rozwiązanie: Przypisz odpowiedzialność klasie, dla której prawdziwe jest jedno z poniższych stwierdzeń: • reprezentuje cały system, podsystem, obiekt leżący najwyżej w hierarchii (ang. root object) • reprezentuje przypadek użycia, w którym operacja systemowa ma miejsce Techniki projektowania - wzorce GRASP Wzorce GRASP– Kontroler
Kontroler reprezentujący cały system, podsystem itp. pełni role fasady dla całej warstwy logiki biznesowej Na ogół kontroler nie posiada wystarczającej wiedzy, aby kompletnie obsłużyć żądanie, stąd jego praca polega na znalezieniu odpowiedniego obiektu z warstwy logiki biznesowej i przekazaniu do niego sterowania (delegacja) Kontroler typu fasada stosuje się w niewielkich systemach, gdzie nie ma zbyt wielu operacji systemowych Jeśli w systemie jest dużo operacji systemowych, wówczas stosuje się kontrolery reprezentujące pojedyncze przypadki użycia, bądź też grupujące kilka przypadków użycia Techniki projektowania - wzorce GRASP Wzorce GRASP– Kontroler
Kontrolery reprezentujące przypadki użycia są w istocie w istocie tworami sztucznymi, nie mającymi odpowiednika w dziedzinie problemu • Kontrolera GRASP nie należy mylić z kontrolerem ze wzorca Model-Widok-Kontroler, który jest elementem warstwy interfejsu użytkownika • Kontroler GRASP należy do warstwy logiki biznesowej (znajduje się na granicy tej warstwy) Techniki projektowania - wzorce GRASP Wzorce GRASP– Kontroler
ROZWIĄZANIE I – KONTROLER TYPU FASADA Klasy pełniące role kontrolerów • Kontroler • Zarządzanie wykonywaniem operacji systemowych • Przechowywanie i udostępnianie obiektów warstwy biznesowej warstwa aplikacji warstwa logiki biznesowej 47
KONTROLER TYPU FASADA – CHARAKTERYSTYKA • Kontroler reprezentujący cały system, podsystem itp. pełni role fasady dla całej warstwy logiki biznesowej • W zakresie odpowiedzialności kontrolera typu fasada leży: • koordynacja działań związanych z wykonywaniem operacji systemowych • przechowywanie i udostępnianie obiektów warstwy logiki biznesowej • Kontroler typu fasada stosuje się w niewielkich systemach, gdzie nie ma zbyt wielu operacji systemowych 48
ROZWIĄZANIE II – KONTROLER TYPU PRZYPADEK UŻYCIA Klasy pełniące role kontrolerów • Kontroler • Zarządzanie wykonywaniem operacji systemowych • Repozytorium • Przechowywanie i udostępnianie obiektów warstwy biznesowej warstwa aplikacji warstwa logiki biznesowej warstwa infrastruktury 49 49
KONTROLER TYPU PRZYPADEK UŻYCIA - CHARAKTERYSTYKA W zakresie odpowiedzialności kontrolera leży koordynacja działań związanych z wykonywaniem operacji systemowych Klasa Repozytorium jest odpowiedzialna za przechowywanie i udostępnianie obiektów warstwy biznesowej Kontrolery reprezentujące pojedyncze przypadki użycia (lub kilka przypadków użycia) stosuje się w bardziej złożonych systemach, gdzie występuje większa liczba operacji systemowych i/lub wymagane jest zapisywanie i odtwarzanie stanu systemu po wykonaniu pewnego ciągu operacji systemowych 50