Projekt oparty na domenie (DDD) sprzeciwia się idei posiadania jednego ujednoliconego modelu dla całego systemu; Zamiast tego zachęca do dzielenia systemu na ograniczone konteksty, z których każdy ma własny model. W fazie strategicznej projektowania DDD mapuje się domenę biznesową i definiuje się ograniczone konteksty dla modeli domeny.
W fazie taktycznej projektowania DDD dokładniej definiuje się modele domeny. Wzorce taktyczne są stosowane w ramach jednego ograniczonego kontekstu. W architekturze mikrousług, gdzie każdy ograniczony kontekst jest kandydatem mikrousługi, szczególnie interesuje nas jednostka i wzorce agregacji. Zastosowanie tych wzorców pomoże nam zidentyfikować naturalne granice dla usług w naszej aplikacji (zobacz następny artykuł w tej serii). Zgodnie z ogólną zasadą mikrousługa nie powinna być mniejsza niż agregacja ani większa niż ograniczony kontekst. Najpierw przejrzymy wzorce taktyczne. Następnie zastosujemy je do kontekstu Wysyłka ograniczona w aplikacji Drone Delivery.
Omówienie wzorców taktycznych
Ta sekcja zawiera krótkie podsumowanie taktycznych wzorców DDD, więc jeśli znasz już DDD, prawdopodobnie możesz pominąć tę sekcję. Wzorce opisano bardziej szczegółowo w rozdziałach 5 – 6 książki Erica Evansa oraz w temacie Implementowanie projektowania opartego na domenie przez Vaughn Vernon.
Jednostki. jednostka jest obiektem o unikatowej, trwałej tożsamości. Na przykład w aplikacji bankowej jednostkami są klienci i konta.
- Jednostka ma unikatowy identyfikator w systemie, który może służyć do wyszukiwania lub pobierania jednostki. Nie oznacza to, że identyfikator jest zawsze udostępniany bezpośrednio użytkownikom. Może to być identyfikator GUID lub klucz podstawowy w bazie danych.
- Tożsamość może obejmować wiele powiązanych kontekstów i może trwać poza okresem istnienia aplikacji. Na przykład numery kont bankowych lub identyfikatory wystawione przez instytucje rządowe nie są powiązane z okresem istnienia określonej aplikacji.
- Atrybuty jednostki mogą ulec zmianie w czasie. Na przykład nazwisko lub adres osoby może ulec zmianie, ale nadal są one tą samą osobą.
- Jednostka może przechowywać odwołania do innych jednostek.
Obiekty wartości. Obiekt wartości nie ma tożsamości. Jest on definiowany tylko przez wartości jego atrybutów. Obiekty wartości są również niezmienne. Aby zaktualizować obiekt wartości, zawsze należy utworzyć nowe wystąpienie w celu zastąpienia starego. Obiekty wartości mogą mieć metody hermetyzujące logikę domeny, ale te metody nie powinny mieć wpływu ubocznego na stan obiektu. Typowe przykłady obiektów wartości obejmują kolory, daty i godziny oraz wartości walutowe.
Agregacje. agregacja definiuje granicę spójności obejmującą co najmniej jedną jednostkę. Dokładnie jedna jednostka w agregacji jest katalogiem głównym. Wyszukiwanie odbywa się przy użyciu identyfikatora jednostki głównej. Wszystkie inne jednostki w agregacji są elementami podrzędnym katalogu głównego i są przywoływana przez następujące wskaźniki z katalogu głównego.
Funkcja agregacji polega na modelowaniu niezmiennych atrybutów transakcyjnych. Elementy w świecie rzeczywistym mają relacje tworzące złożone sieci. Klienci tworzą zamówienia, zamówienia zawierają produkty, produkty mają dostawców itd. Jak zagwarantować spójność, jeśli aplikacja zmodyfikuje kilka powiązanych obiektów? Jak śledzić niezmienne atrybuty i je wymuszać?
Tradycyjne aplikacje często używały transakcji bazy danych w celu wymuszania spójności. Jednak w aplikacji rozproszonej często nie jest to możliwe. Pojedyncza transakcja biznesowa może obejmować wiele magazynów danych lub może być długotrwała lub może obejmować usługi innych firm. Ostatecznie jest to aplikacja, a nie warstwa danych, aby wymusić niezmienności wymagane dla domeny. To właśnie są agregacje przeznaczone do modelowania.
Uwaga
Agregacja może składać się z jednej jednostki bez jednostek podrzędnych. Co sprawia, że jest to agregacja, to granica transakcyjna.
Usługi domenowe i aplikacji. w terminologii DDD usługa jest obiektem, który implementuje pewną logikę bez przechowywania żadnego stanu. Evans rozróżnia usługi domenowe, które hermetyzują logikę domeny i usługi aplikacji, które zapewniają funkcje techniczne, takie jak uwierzytelnianie użytkowników lub wysyłanie wiadomości SMS. Usługi domenowe są często używane do modelowania zachowań obejmujących wiele jednostek.
Uwaga
Termin usługa jest przeciążona w tworzeniu oprogramowania. Definicja w tym miejscu nie jest bezpośrednio powiązana z mikrousługami.
Zdarzenia domeny. zdarzenia domeny mogą służyć do powiadamiania innych części systemu, gdy coś się zdarzy. Zgodnie ze swoją nazwą zdarzenia domeny powinny dotyczyć czegoś w domenie. Na przykład wstawienie rekordu do tabeli nie jest zdarzeniem domeny. "Anulowano dostarczanie" to zdarzenie domeny. Zdarzenia domeny są szczególnie istotne w architekturze mikrousług. Mikrousługi są rozproszone i nie współdzielą magazynów danych, dlatego zdarzenia domeny umożliwiają ich koordynowanie. W artykule Komunikacja międzyusługowa omawia bardziej szczegółowo asynchroniczne komunikaty.
Istnieje kilka innych wzorców DDD, których nie wymieniono tutaj, w tym fabryk, repozytoriów i modułów. Mogą to być przydatne wzorce podczas implementowania mikrousługi, ale są one mniej istotne podczas projektowania granic między mikrousługą.
Dostarczanie dronów: stosowanie wzorców
Zaczynamy od scenariuszy, które musi obsługiwać ograniczony kontekst Wysyłka.
- Klient może poprosić drona o odebranie towarów z firmy zarejestrowanej w usłudze dostarczania dronów.
- Nadawca generuje tag (kod kreskowy lub RFID), który ma być umieszczany w pakiecie.
- Dron będzie pobierać i dostarczać pakiet z lokalizacji źródłowej do lokalizacji docelowej.
- Gdy klient planuje dostawę, system udostępnia ETA na podstawie informacji o trasach, warunków pogodowych i danych historycznych.
- Gdy dron jest w locie, użytkownik może śledzić bieżącą lokalizację i najnowszą wartość ETA.
- Do momentu odebrania pakietu przez drona klient może anulować dostawę.
- Klient jest powiadamiany o zakończeniu dostawy.
- Nadawca może zażądać potwierdzenia dostarczenia od klienta w postaci podpisu lub odcisku palca.
- Użytkownicy mogą wyszukać historię ukończonego dostarczania.
W tych scenariuszach zespół deweloperów zidentyfikował następujące jednostki.
- Dostawa
- Pakiet
- Dron
- Klient
- Potwierdzenie
- Powiadomienie
- Tag
Pierwsze cztery, dostarczanie, pakiet, dron i konto, są agregacjami reprezentującymi granice spójności transakcyjnej. Potwierdzenia i powiadomienia są jednostkami podrzędnymi dostaw, a tagi są jednostkami podrzędnymi paczek.
Obiekty wartości w tym projekcie obejmują Lokalizację, ETA, PackageWeight i PackageSize.
Aby zilustrować, poniżej przedstawiono diagram UML agregacji dostarczania. Zwróć uwagę, że zawiera odwołania do innych agregacji, w tym konta, pakietu i drona.
Są dwa zdarzenia domeny:
Podczas lotu jednostka drona wysyła zdarzenia DroneStatus (Stan drona), które opisują lokalizację i stan drona (przelot, wylądował).
Jednostka dostawy wysyła zdarzenia DeliveryTracking (Śledzenie dostawy) po każdej zmianie etapu dostawy. Są to następujące zdarzenia: DeliveryCreated (Utworzenie dostawy), DeliveryRescheduled (Ponowne zaplanowanie dostawy), DeliveryHeadedToDropoff (Przelot do miejsca docelowego) i DeliveryCompleted (Ukończenie dostawy).
Należy zwrócić uwagę, że zdarzenia te opisują rzeczy, które są istotne w ramach modelu domeny. Opisują one elementy domeny i nie są powiązane z konkretnymi konstrukcjami języka programowania.
Ponadto zespół deweloperów określił obszar funkcjonalności, który nie pasuje do żadnej z opisanych jednostek. Jakaś część systemu musi koordynować wszystkie działania związane z planowaniem lub aktualizacją dostawy. W związku z tym zespół programistyczny dodał do projektu dwie usługi domenowe: harmonogram, który koordynuje kroki, oraz nadzorcę, który monitoruje stan każdego kroku, aby wykryć, czy jakiekolwiek kroki zakończyły się niepowodzeniem, czy upłynął limit czasu. Jest to odmiana wzorca nadzorcy agenta harmonogramu.
Następne kroki
Następnym krokiem jest zdefiniowanie granic dla każdej mikrousługi.