Projektowanie Zorientowane na Dziedzinę ang. Domain Driven Design
2 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
3 Domain Driven Design (DDD) Domain Driven Design jest koncepcją / stylem analizy i 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ą
Klasyczny model aplikacji Warstwa prezentacji Warstwa aplikacji Warstwa logiki biznesowej Warstwa Infrastruktury Warstwa prezentacji odpowiada za interpretację i wykonywanie poleceń użytkownika oraz prezentację danych Warstwa aplikacji kieruje wykonanie zadań do odpowiednich obiektów warstwy logiki biznesowej oraz koordynuje wykonywanie zadań (orkiestracja) Warstwy logiki biznesowej tutaj ma miejsce właściwa realizacja zadań, dla których system został stworzony Warstwa infrastruktury służy do zapisywania danych i stanu systemu 4
5 Podstawowe elementy składowe Encja (ang. Entity) Wartość (ang. Value Object) Serwis (ang. Service) Agregat (ang. Aggregate) Repozytorium (ang. Repository) Fabryka (ang. Factory)
Charakterystyka obiektu Tożsamość coś co powoduje, że obiekt jest odróżnialny od innych obiektów Stan zbiór wartości wszystkich cech (atrybutów) obiektu oraz powiązań między obiektami Zachowanie zbiór wszystkich usług, jakie obiekt potrafi wykonać na rzecz innych obiektów 6
Entity vs. Value object przykłady Entity obiekt klasy Osoba może zmienić wartość atrybutów (np. kolor włosów, waga, wiek), ale nadal jest postrzegany jako ta sama osoba o jego tożsamości nie decydują wartości atrybutów Value object obiekt klasy Punkt po zmianie wartości dowolnego atrybutu (np. współrzędna X, współrzędna Y) jest postrzegany jako inny obiekt o jego tożsamości decydują wartości atrybutów 7
8 Entity Object vs. Value Object Entity Tożsamość jest niezależna od stanu obiektu Obiekt może zmienić stan i nadal jest postrzegany jako ten sam obiekt Przykłady: Osoba, Rachunek (bankowy), Produkt (w sklepie) Value Object Tożsamość obiektu stanowi jego stan Obiekt po zmianie stanu jest postrzegany już jako inny obiekt Przykłady: Punkt (współrzędne X i Y), Adres, Pieniądz, Data
9 Value object Value object są niezmienne (ang. immutable) raz utworzony nie może być zmieniony Można je przekazywać jako argumenty metod bez obawy o skutki uboczne (nie mogą być zmienione) W odróżnieniu od starszych braci, czyli DTO (ang. Data Transfer Object) zawierają nie tylko atrybuty ale również metody (np. do walidacji)
10 Entity i Value Object przykłady Entity Wydarzenie Osoba Uczestnictwo Value Object Alarm Adres
Identyfikatory (1) Tożsamość obiektu najłatwiej stworzyć przy pomocy unikalnych identyfikatorów Jako identyfikator można wykorzystać dowolny atrybut o unikalnych wartościach, np. PESEL, nr rejestracyjny Obiekty typu Value nie muszą posiadać identyfikatorów, ponieważ ich tożsamość jest związana z stanem zmiana stanu to zmiana tożsamości, w efekcie oznacza to 11 nowy obiekt
Identyfikatory (2) Każdy obiekt typu Entity powinien posiadać identyfikator, niezmienny przez cały cykl życia obiektu Identyfikator obiektów typu Entity pozwala na ustalenie tożsamości obiektów o identycznych wartościach atrybutów (np. dwie osoby o identycznych danych) Identyfikator obiektów typu Entity pozwala na ochronę tożsamości obiekt po zmianie swojego stanu jest rozpoznawany jako ten sam obiekt 12
13 Agregat 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 elementami wewnętrznymi korzeń agregatu agregat element wewnętrzny
14 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 Każdy obiekt wewnętrzny musi być powiązany bezpośrednio lub pośrednio z korzeniem
15 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 istnieje możliwość kontroli działań wykonywanych na obiektach wewnętrznych, co również sprzyja utrzymaniu integralności danych Agregat upraszcza model systemu system może być traktowany jako zbiór agregatów i związków pomiędzy nimi. Z reguły agregatów jest mniej niż klas, liczba związków pomiędzy nimi również
16 Identyfikacja agregatów Jeżeli obiekty klasy A mogą występować 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 występują 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 Jeśli w pewnej grupie obiektów usunięcie jednego z nich oznacza, że pozostałe tracą rację bytu, wówczas grupa tych obiektów jest kandydatem na agregat (reguła kaskadowego usuwania) Kandydatem na agregat są klasy powiązane przy pomocy kompozycji
17 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 korzeń 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 agregat 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 korzeń 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ętrznymi w agregacie Wydarzenie
18 Dostęp do obiektów biznesowych (1) 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
19 Dostęp 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
20 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
21 Repozytorium - przykład Repozytorium wydarzeń obsługuje agregat Wydarzenie. Repozytorium będzie zawierać takie metody jak: ZnajdzWydarzenie() ZapiszWydarzenie() UsunWydarzenie() warstwa logiki biznesowej warstwa infrastruktury Repozytorium osób obsługuje agregat Osoba. Repozytorium będzie zawierać takie metody jak: ZnajdzOsobe() ZapiszOsobe() UsunOsobe()
22 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 Serwisy mogą występować w warstwie aplikacji (koordynacja działań, orkiestracja) lub też w warstwie logiki biznesowej (przekształcanie jednego agregatu w inny, np. wygenerowanie zestawienia, raportu, pliku pdf, lub też po to by nie przeciążać klasy biznesowej)
23 Serwis 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
24 Operacja systemowa - DodajUczestnika() Operacja: DodajUczestnika(idWydarzenie, idosoba) Przypadki użycia: UC3 Dodaj uczestnika Warunki początkowe: Istnieje instancja w klasy Wydarzenie o identyfikatorze idwydarzenie Istnieje instancja o klasy Osoba o identyfikatorze idosoba Warunki końcowe: Utworzono instancje u klasy Uczestnictwo Atrybutowi u.status przypisano wartość Niepotwierdzone Utworzono powiązanie pomiędzy u i w Utworzono powiązanie pomiędzy u i o
Projektowanie interakcji wg DDD 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 25
26 Diagram sekwencji dla operacji systemowej DodajUczestnika() Serwis Wydarzeń znajduje obiekt Wydarzenie w Repozytorium Wydarzeń oraz obiekt Osoba w Repozytorium Osób Komunikat systemowy DodajUczestnika() jest odbierany przez obiekt Serwis Wydarzeń Wydarzenie tworzy obiekt klasy Uczestnik i dodaje go do swojej listy (DodajUczestnika) Serwis Wydarzeń deleguje wykonanie operacji dodania uczestnika do obiektu Wydarzenie przekazując mu obiekt Osoba
27 Model projektowy diagram klas (po aktualizacji) Nowe atrybuty Nowe związki Nowe metody
28 Literatura Eric Evans: Domain-Driven Design: Tackling Complexity in the Heart of Software Tim McCarthy:.Net Domain Driven Design with C# http://www.infoq.com/minibooks/domaindriven-design-quickly