DDD – Domain-Driven Design (Projektowanie oparte na domenie)
Gdy codziennie opracowywane są nowe technologie, powstaje mnóstwo nowych i niedojrzałych systemów. I pytanie brzmi, w jaki sposób inżynierowie oprogramowania rozwijają się w tym szybko zmieniającym się środowisku i tworzą nowe systemy, które jak najbardziej wytrzymują próbę czasu?
Do tej pory wynaleziono wiele architektur, aby obniżyć koszty oprogramowania i zwiększyć żywotność samego oprogramowania. Te architektury obejmuje architekturę wielowarstwową i wielopoziomową, a następnie architekturę zorientowaną na domenę. To powiedziawszy, chcę wspomnieć o koncepcji, która nie jest nowa, ale jest uważana za skuteczne podejście do tworzenia większości aplikacji w dzisiejszych czasach. Jest to projektowanie oparte na domenie znane również jako DDD. Jego połączenie, udoskonalenie i wybitny rozwój pokonują wady popularnych starych modeli, takich jak N-Tiers, MVC, MVP, MVVM.
I teraz chcę omówić kilka podstawowych koncepcji wzorca DDD.
Co to jest projektowanie oparte na domenie i dlaczego go potrzebujemy?
W 2003 roku Eric Evan opublikował pierwszą książkę zatytułowaną „Tackling Complexity in the Heart of Software”, która wprowadziła pierwsze koncepcje do DDD. Od tego czasu popularność DDD gwałtownie wzrosła. Wiele zespołów programistycznych zastosowało ten model i osiągnęło wielki sukces w tworzeniu oprogramowania. Kilku gigantów technologicznych, takich jak Microsoft, nie wychodzi z tego trendu i wspomnieli o projektowaniu opartym na domenach w następujący sposób:
„Projektowanie oparte na domenie (DDD) opowiada się za modelowaniem opartym na realiach biznesowych, które są odpowiednie dla Twoich przypadków użycia. W kontekście budowania aplikacji DDD mówimy o problemach jako o domenach. Opisujemy niezależne obszary problemów jako ograniczone konteksty (każdy ograniczony kontekst jest skorelowany z mikrousługą) i podkreśla wspólny język, w którym można rozmawiać o tych problemach. Sugeruje również wiele koncepcji i wzorców technicznych, takich jak encje domeny z bogatymi modelami (bez modelu domeny anemicznej), obiekty wartości, agregaty i reguły agregacji root (lub encji głównej) w celu wsparcia wewnętrznej implementacji…”
DDD to podejście do tworzenia oprogramowania zorientowanego na biznes. Problemy i wyzwania, które pojawiają się podczas tworzenia i utrzymania oprogramowania, w większości wynikają z ciągłego rozwoju firmy. W ten sposób DDD pomaga nam ściśle powiązać rozwój oprogramowania z ewolucją naszego modelu biznesowego.
DDD pomaga rozwiązać problem budowania złożonych systemów. Ten wzorzec wymaga od architektów, programistów i ekspertów domeny dokładnego zrozumienia wymagań. Następnie definiują zachowania, rozumieją reguły, stosują zasady i logikę biznesową w zestawie klauzul (abstrakcje, interfejsy itd.). Następnie inżynierowie zaimplementują je w różnych warstwach (np. warstwa domeny, warstwa aplikacji, warstwa infrastruktury). Obecnie DDD jest standardem w opracowywaniu różnych popularnych architektur, takich jak architektura cebulowa, czysta architektura, architektura heksagonalna itp.
Wyjaśnimy teraz niektóre zalety i wady projektowania opartego na domenie, aby pomóc Ci zrozumieć, czy ten model dobrze pasuje do Twojego projektu, czy nie.
Zalety i wady projektowania opartego na domenie
Zalety DDD
Loose coupling(Luźne połączenie)
Części systemu będą ze sobą współdziałać poprzez definicje i zasady określone w warstwie Core (interfejsy, klasy abstrakcyjne, klasy bazowe itp.). W pozostałych warstwach zostaną zakończone wdrożenia. Konfiguracja wdrożenia będzie odbywać się za pomocą bibliotek DI (IoC, AutoFac). Dzięki temu zespoły mogą jednocześnie rozwijać się niezależnie.
Flexibility(Elastyczność)
Luźne połączenia i definicje wysokiego poziomu pozwalają zespołowi na bardziej elastyczne ulepszanie i dostosowywanie się do nowych wymagań funkcjonalnych bez znaczącego wpływu na cały system.
Testability(Testowalność)
Jak wspomniano powyżej, oddzielając implementację od interfejsów zdefiniowanych w warstwie Core, dozwolone jest testowanie z mock data w osobnym środowisku.
Maintenance(Utrzymanie, konserwacja)
DDD wyraźnie dzieli funkcje między warstwy. W szczególności Domena implementuje logikę biznesową, Infrastruktura odpowiada za trwałość danych, a Aplikacja obsługuje API i logikę integracji. Podążanie za tym podejściem ostatecznie daje szanse na pisanie czystszych i bardziej niezawodnych kodów. Ponadto Twój zespół może łatwo znaleźć kod, ograniczyć jego duplikację i skrócić czas konserwacji.
Wady DDD
Wiedza o domenach
DDD wymaga rozległej wiedzy o domenach. Oznacza to, że Twój zespół musi mieć co najmniej jednego eksperta domenowego. Ekspert pomorze Ci zdefiniować wszystkie procesy, procedury i terminologię w tej dziedzinie.
Koszty rozwoju
Eksperci domen i zespół muszą wdrożyć dużą ilość izolacji i enkapsulacji w modelu domeny. Często skutkuje to dłuższym rozwojem i czasem trwania, co może mieć stosunkowo wysokie koszty. Dlatego nie nadaje się do projektów krótkoterminowych lub projektów bez dużej złożoności domeny.
Niskie interakcje
Luźne połączenie między różnymi częściami wymaga od zespołu regularnej komunikacji i wymiany informacji. Dlatego przed zastosowaniem podejścia DDD zespół musi najpierw szczegółowo omówić jego zasady.
Warstwy w DDD
Architektura projektów DDD składa się zazwyczaj z trzech głównych części:
Domena
Infrastruktura
Aplikacja
W zależności od wielkości każdego projektu możemy ułożyć te części w projekcie lub rozdzielić je na różne warstwy.
Warstwa Domeny
Miejsce do definiowania pojęć logicznych, zasad, wzorców i zachowań danych, w tym walidacji domeny, obliczeń i wyrażeń dla operacji systemowych.
Entities (Encje)
Klasy POCO, konstrukcja i walidacja modelu.
Aggregate (Agregaty)
Reguły, obliczenia, logika domen i powiązane obiekty podczas aktualizacji domeny. Według Martina Fowlera agregat to klaster obiektów domeny, który można traktować jako pojedynczą jednostkę.
Value objects (Obiekty wartości)
Wartość obiektu powiązanego z jednostkami domeny. W zasadzie ValueObjects nie mają tożsamości i po zainicjowaniu nie będą modyfikowane. Można je rozumieć jako klasy niezmienne.
Interfaces(Interfejsy)
Pomagają zdefiniować zachowania biznesowe itp. Inne warstwy będą odpowiedzialne za implementację tych definicji.
Repository Interfaces/ServiceBase (Interfejsy repozytorium/ServiceBase)
Interfejsy repozytoriów ogólnych, repozytoriów domen i usług. Inne warstwy będą je dziedziczyć i rozwijać.
ILogger/DTOs/Exceptions (Ilogger/DTO,/Wyjątki)
Powiadomienia i informacje są przesyłane do innych usług.
Inne
Warstwa Aplikacji
Mobilna aplikacja
Webowa aplikacja MVC/API
Aplikacja pulpitu
IoT
Inne usługi
Warstwa Infrastruktury
Repositories (Repozytoria)
W tym miejscu zostaną zaimplementowane repozytoria, w tym GenericRepository i <Entity>Repository.
Data access (Dostęp do danych)
Konteksty i połączenia API łączą się z bazami danych.
SQL: ADO.NET, EntityFramework, Dapper i ORM itp.
in-Memory
Caching, NoSQL, and so on.
Data seeding
Inne
Logowanie.
Kryptografia.
Itp.
Keep up the good work!