- Pierwszą część książki: Domain Driven Design
- albo po polsku
O jakim problemie mowa?
Powiedzmy, że rozpoznajemy, co też dzieje się domenie sklepu internetowego (nie wiem dlaczego to sklep zazwyczaj przychodzi na myśl:)). Powiedzmy, że dzieje się jak poniżej:Jest to jakaś interakcja pomiędzy obiektami w dziedzinie.
Gdy zaczynamy modelować, naturalnie pojawiają się klasy takie jak: Zamówienie, Koszyk, itd. Powstaje model złożony z powiedzmy 30-50 klas. Wszystko wygląda super świetnie, ale zbiegiem czasu coś zaczyna nie grać. Pojawiają się następujące symptomy:
- W związku z kolejnymi wymaganiami, do obiektów dochodzi coraz więcej atrybutów i metod
- Programista implementujący przypadek użycia związany ze złożeniem zamówienia z trudem odnajduje się w gąszczu atrybutów i metod dodanych przez kogoś, kto implementował realizację Zamówienia
- Niektóre obiekty są używane w tak wielu miejscach systemu, że jakakolwiek w nich zmiana ma spore skutki w innych odległych miejscach
Niby wszystko zostało przygotowane zgodnie z regułami sztuki, ale jednak wszyscy czują, że coś śmierdzi...tylko nie wiadomo z jakiej przyczyny.
Powód jest taki, że ten sam obiekt modelu używany jest wielu różnych kontekstach. Zamówienie wynikające z interakcji użytkownika z Koszykiem jest nieco inną sprawą niż Zamówienie realizowane przez magazyn.
"Bounded context should have a name so that you can talk about them"
Rację mieli starzy Indianie, gdy twierdzili, że jeśli poznasz czyjeś imię, zyskujesz nad tym kimś władzę. Nie inaczej jest z bounded contexts. Jeśli nie zauważymy i nie nazwiemy kontekstów użycia modelu, to mogą nam zrobić krzywdę. Nienazwane lubią się mieszać i dokładać do obiektów modelu rożnego rodzaju dodatki właściwe dla swej specyfiki. W skutek czego powstaje model-potworek, który w założeniu miał być super, a w wykonaniu i tak jest kolejną wersją big ball of mud.Jeden model w jednym kontekście
W związku z dokonanymi odkryciami warto zalecać:- Nazwij kontekst, w którym może być wykorzystywany model. Już sama próba nazwania sprawi, że kontekstów pojawi się kilka (o ile tam są).
- Jeden model może być wykorzystywany tylko w jednym kontekście (bounded context). Zamówienie w kontekście Koszyka to nie dokładnie to samo, co zamówienie w kontekście Magazynu.
- Odizoluj poszczególne konteksty i właściwe im modele od siebie
W powyższych zasadach można dopatrzyć się echa Single Resposibility Principle. Z odpowiedzialności modelu powinien wynikać jednoznaczny kontekst jego użycia. Tyle, że Bounded Context definiuje to wprost i wyraźnie, a z zasady odpowiedzialności trzeba sobie wywnioskować.
Jeżeli w konsekwencji mamy zdefiniowanych kilka zwartych modeli o jednoznacznie określonych kontekstach użycia, to musi istnieć coś, co będzie potrafiło skonwertować obiekty z jednego kontekstu w drugi (jeśli jest taka potrzeba). W DDD ta potrzeba jest zaspokajana poprzez zdefiniowanie Context map w postaci zestawu usług-translatorów (w apachowych commonsach nazywanych transformerami). Ich odpowiedzialność to właśnie konwersja.
Podsumowując zyski z wprowadzenia konceptu Bounded Context:
- Redukcja echa w systemie - zmiana w modelu w jednym miejscu nie skutkuje oddźwiękiem w innym
- Zmiany wynikające z biznesu mają na poziomie architektury ograniczony do kontekstu zasięg
- Można lepiej zorganizować prace nad projektem (tutaj DDD proponuje kilka pomysłów w zależności od tego jakie relacje występują pomiędzy kontekstami).
Innym wartym wspomnienia sposobem na realizację komunikacji między kontekstami jest model zdarzeniowy.
ReplyDeleteDzięki :)
ReplyDeleteW ogólności konteksty mogą integrować się poprzez:
ReplyDelete- dane - gdzie np Repozytorium jednego kontekstu pobieranie sobie część danych z serivsu apliakcyjnego drugiego kontekstu (drugi kontekst ukrywa model, zwraca rodzaj projekcji)
- czynności - najprostszy scenariusz, gdzie po prostu wołamy serwisy z innego kontekstu
- zdarzenia - o których właśnie pisał Krzysztof. Dają nam decoupling (ze wszystkimi konsekwencjami), umożliwiają odcięcie się od strzałki czasu (asynch), architekturę pluginową...
A orkiestracja wielu zdarzeń jest możliwa dzięki Sagom biznesowym.
Ale za każdym razem kluczowe jest hermetyzowanie modelu danego kontekstu (znowu zasada OO na poziomie arch. apliakcji).
@Sławek
ReplyDeleteNie mogłem już dłużej wytrzymać braku postów na twoim blogu i wiedziałem, że to Cie sprowokuje :)
Spójrzmy przez pryzmat DDD na rozdział From the Mud to Structure z POSA 4. Takie np. Shared Repository przedstawia komunikację między komponentami poprzez dane. Dobre dla systemów data-driven - np. jakieś aplikacje pomiarowe. Mejk sens?
Czy przypadkiem przekazanie "czegoś" do innego kontekstu to nie "żądanie", które w odpowiedzi dostaje "obiekt" w odpowiedzi, nie koniecznie "żądany" obiekt a jego "kopię" lub wersję?
ReplyDeleteJeżeli konteksty były by obsługiwane przez odrębne podsystemy (komponenty) przekazanie czegokolwiek między nimi właśnie tak by wyglądało (to coś jak zaświadczenie w urzędzie: dostaje jakiś pełny lub częściowy odpis tego co urząd ma...)