Analizowanie aplikacji i identyfikowanie granic dekompozycji

Ukończone

Aby przenieść aplikację do architektury mikrousług, firma Fabrikam musi ocenić bieżącą aplikację i określić zakres i granice każdej mikrousługi. W tej ocenie będą używać frameworku projektowania opartego na domenie (DDD). Zobaczmy, jak stosują ją do swojej aplikacji.

Notatka

W tym artykule nie przedstawiono kompletnej i kompleksowej analizy domeny. Celowo zachowaliśmy krótki przykład, aby zilustrować główne kwestie. Aby uzyskać więcej informacji na temat DDD, zobacz sekcję "Dowiedz się więcej" w podsumowaniu na końcu tego modułu.

Co to jest projekt oparty na domenie?

DDD to podejście do projektowania systemu pierwotnie wprowadzonego przez Erika Evansa w książce Domain-Driven Design 2005: Walka ze złożonością w centrum oprogramowania. Takie podejście obejmuje trzy kluczowe elementy:

  • Skup się na podstawowej domenie i logice domeny.
  • Struktura projektu w modelu domeny.
  • Wspieranie iteracyjnej współpracy między zespołami technicznymi i partnerami biznesowymi w celu ciągłego ulepszania systemu.

DDD zapewnia framework, który może pomóc w drodze do stworzenia zestawu dobrze zaprojektowanych mikrousług. Ma dwie odrębne fazy, strategiczne i taktyczne. W strategii DDD definiuje się strukturę systemu na dużą skalę. Strategia DDD pomaga zapewnić, że architektura jest skoncentrowana na możliwościach biznesowych. Taktyczne DDD zapewnia zestaw wzorców projektowych, których można użyć do utworzenia modelu domeny. Wzorce te obejmują jednostki, agregacje i usługi domenowe. Te wzorce taktyczne ułatwiają projektowanie mikrousług luźno powiązanych i spójnych.

Diagram kroków projektowania opartego na domenie.

Podczas strategicznej fazy DDD należy zamapować domenę biznesową i zdefiniować powiązane konteksty dla modeli domeny. Taktyczne DDD polega na definiowaniu modeli domeny z większą precyzją. Wzorce taktyczne są stosowane w ramach jednego ograniczonego kontekstu. W architekturze mikrousług interesuje nas jednostka i wzorce agregacji. Zastosowanie tych wzorców pomaga nam zidentyfikować naturalne granice usług w naszej aplikacji. Ogólnie rzecz biorąc, mikrousługi nie powinny być mniejsze niż agregacja i nie większe niż ograniczony kontekst.

Na wysokim poziomie ten proces można podzielić na cztery kroki:

  1. Przeanalizuj domenę biznesową, aby zrozumieć wymagania funkcjonalne aplikacji. Dane wyjściowe tego kroku to nieformalny opis domeny, który można udoskonalić w bardziej formalnym zestawie modeli domeny.
  2. Zdefiniuj ograniczone konteksty domeny. Każdy ograniczony kontekst zawiera model domeny, który reprezentuje określoną poddomenę większej aplikacji.
  3. W kontekście ograniczonym zastosuj taktyczne wzorce DDD, aby zdefiniować jednostki, agregacje i usługi domenowe.
  4. Zidentyfikuj mikrousługi w aplikacji przy użyciu wyników z poprzedniego kroku.

Przyjrzyjmy się bliżej temu, co się dzieje w każdym z tych kroków.

Analizowanie domeny biznesowej

DDD rozpoczyna się od modelowania domeny biznesowej i tworzenia modelu domeny. Model domeny jest abstrakcyjnym modelem domeny biznesowej. Destyluje i porządkuje wiedzę o domenie oraz udostępnia wspólny język dla deweloperów i ekspertów z dziedziny.

Zacznij od mapowania wszystkich funkcji biznesowych i ich połączeń. Ta analiza to wspólny wysiłek, który obejmuje ekspertów z dziedziny, architektów oprogramowania i innych uczestników projektu. Nie musisz używać żadnego konkretnego formalizmu. Szkicuj diagram lub rysuj go na tablicy.

Podczas wypełniania diagramu możesz zacząć identyfikować odrębne poddomeny. Które funkcje są ściśle powiązane? Które funkcje są kluczowe dla firmy i które zapewniają usługi pomocnicze? Co to jest wykres zależności? W tej początkowej fazie nie zajmujesz się technologiami ani szczegółami implementacji. Należy zauważyć miejsce, gdzie aplikacja musi zostać zintegrowana z zewnętrznymi systemami, na przykład CRM, przetwarzaniem płatności lub systemami rozliczeniowymi.

Diagram domeny biznesowej.

Definiowanie ograniczonych kontekstów

Model domeny zawiera reprezentacje rzeczywistych rzeczy na świecie, takich jak użytkownicy, drony i pakiety. Nie oznacza to jednak, że każda część systemu musi używać tych samych reprezentacji dla tych samych rzeczy.

Na przykład podsystemy obsługujące naprawę dronów i analizę predykcyjną muszą reprezentować wiele cech fizycznych dronów. Te cechy obejmują historię konserwacji, przebieg, wiek, numer modelu i szczegóły wydajności. Ale kiedy nadszedł czas na zaplanowanie dostawy, nie dbamy o te rzeczy. Podsystem planowania musi tylko wiedzieć, czy dron jest dostępny i szacowany czas przybycia (ETA) do odbioru i dostawy.

Jeśli spróbujemy utworzyć pojedynczy model dla obu tych podsystemów, jest to bardziej złożone niż potrzebujemy. W miarę upływu czasu staje się również trudniejsza ewolucja modelu, ponieważ wszelkie zmiany muszą spełniać wiele zespołów pracujących nad oddzielnymi podsystemami. Często lepiej jest zaprojektować oddzielne modele reprezentujące tę samą jednostkę w świecie rzeczywistym (w tym przypadku drona) w dwóch różnych kontekstach. Każdy model zawiera tylko funkcje i atrybuty, które są istotne w określonym kontekście.

To podejście wykorzystuje koncepcję DDD ograniczonych kontekstów. Ograniczony kontekst jest po prostu granicą w domenie, w której ma zastosowanie określony model domeny. Patrząc na poprzedni diagram, możemy grupować funkcje zgodnie z tym, czy różne funkcje współdzielą jeden model domeny.

Diagram ograniczonych kontekstów dla aplikacji dronów.

Definiowanie jednostek, agregacji i usług

Taktyczne DDD polega na precyzyjnym definiowaniu modeli domenowych. Wzorce taktyczne są stosowane w ramach jednego ograniczonego kontekstu. W architekturze mikrousług interesuje nas jednostka i wzorce agregacji. Zastosowanie tych wzorców pomaga nam zidentyfikować naturalne granice usług w naszej aplikacji. Ogólnie rzecz biorąc, mikrousługi nie powinny być mniejsze niż agregacja i nie większe niż ograniczony kontekst.

Istnieje kilka taktycznych wzorców DDD, które należy wziąć pod uwagę:

  • Jednostki: Jednostka jest obiektem o unikatowej tożsamości, która utrzymuje się w czasie. Na przykład w aplikacji bankowej klienci i konta są jednostkami.
  • Obiekty wartości: Obiekt wartości nie ma tożsamości. Wartości atrybutów definiują je i są niezmienne. Typowe przykłady obiektów wartości obejmują kolory, daty i godziny oraz wartości waluty.
  • Agregacje: Agregacja definiuje granicę spójności wokół co najmniej jednej jednostki. Celem agregacji jest modelowanie wariancji transakcyjnych. Rzeczy w świecie rzeczywistym mają złożone sieci relacji. Klienci tworzą zamówienia, zamówienia zawierają produkty, produkty mają dostawców itd. Jeśli aplikacja modyfikuje kilka powiązanych obiektów, jak gwarantuje spójność? Jak śledzić niezmienniki i wymuszać je?
  • usług domenowych 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. Usługi aplikacji zazwyczaj obejmują funkcje techniczne, takie jak uwierzytelnianie użytkowników lub wysyłanie wiadomości SMS. Usługi domenowe są często używane do modelowania zachowania obejmującego wiele jednostek.
  • Zdarzenia domeny: Zdarzenia domeny mogą być używane do powiadamiania innych części systemu, gdy coś się wydarzy. Jak sugeruje nazwa, zdarzenia domeny powinny oznaczać coś w domenie. Na przykład "rekord został wstawiony do tabeli" nie jest zdarzeniem domeny. "Anulowanie dostawy" to zdarzenie domeny. Zdarzenia domeny są szczególnie istotne w architekturze mikrousług. Ponieważ mikrousługi są dystrybuowane i nie udostępniają magazynów danych, zdarzenia domeny umożliwiają mikrousługi koordynowanie się ze sobą.

Diagram modelu domeny drona.

W swoim systemie zespół deweloperów firmy Fabrikam zidentyfikował następujące jednostki:

  • Dostawa
  • Pakiet
  • Dron
  • Rachunek
  • Potwierdzenie
  • Powiadomienie
  • Znacznik

Pierwsze cztery jednostki, dostarczanie, pakiet, dron i konto są agregacjami reprezentującymi granice spójności transakcyjnej. Potwierdzenia i powiadomienia są podrzędnymi jednostkami dostaw. Tagi to podrzędne jednostki pakietów.

Obiekty wartości w tym projekcie obejmują Lokalizację, ETA, PackageWeight i PackageSize.

Istnieją dwa zdarzenia domeny:

  • Gdy dron jest w locie, moduł drona wysyła zdarzenia statusu drona, które opisują jego lokalizację i stan, na przykład w trakcie lotu lub po wylądowaniu.
  • Jednostka dostarczania wysyła zdarzenia DeliveryTracking za każdym razem, gdy etap dostawy ulegnie zmianie. Te zdarzenia obejmują: DeliveryCreated, DeliveryRescheduled, DeliveryHeadedToDropoff i DeliveryCompleted.

Zwróć uwagę, że te zdarzenia opisują istotne elementy w modelu domeny. Opisują coś o domenie i nie są powiązane z konkretną konstrukcją języka programowania.

Zespół deweloperów zidentyfikował jeszcze jeden obszar funkcjonalności, który nie pasuje starannie do żadnej z opisanych do tej pory jednostek. Część systemu musi koordynować wszystkie kroki związane z planowaniem lub aktualizowaniem dostawy. Zespół deweloperów dodał do projektu dwie usługi domenowe. Harmonogram koordynuje kroki. Nadzorca monitoruje stan każdego kroku, aby wykryć, czy jakiekolwiek kroki zakończyły się niepowodzeniem, czy upłynął limit czasu.

Identyfikowanie mikrousług

Teraz możemy przejść od modelu domeny do projektu aplikacji. Oto podejście, którego można użyć do uzyskiwania mikrousług z modelu domeny.

  1. Zacznij od ograniczonego kontekstu. Ogólnie rzecz biorąc, funkcjonalność mikrousługi nie powinna obejmować więcej niż jednego ograniczonego kontekstu. Zgodnie z definicją ograniczony kontekst oznacza granicę określonego modelu domeny. Jeśli mikrousługa łączy ze sobą różne modele domeny, może być konieczne uściślinie analizy domeny.
  2. Następnie przyjrzyj się agregacji w modelu domeny. Agregacje są często dobrymi kandydatami do mikrousług. Dobrze zaprojektowana agregacja przedstawia wiele cech dobrze zaprojektowanej mikrousługi:
    • Agregacja pochodzi z wymagań biznesowych, a nie kwestii technicznych, takich jak dostęp do danych lub obsługa komunikatów.
    • Agregacja powinna mieć wysoką spójność funkcjonalną.
    • Agregacja jest granicą trwałości.
    • Agregacje powinny być luźno powiązane.
  3. Usługi domenowe są również dobrymi kandydatami do mikrousług. Usługi domenowe to operacje bezstanowe w wielu agregacjach. Typowym przykładem jest przepływ pracy obejmujący kilka mikrousług. Później zobaczymy przykład usługi domeny w aplikacji Drone Delivery.
  4. Na koniec należy wziąć pod uwagę wymagania niefunkcjonalne. Przyjrzyj się czynnikom, takim jak rozmiar zespołu, typy danych, technologie, wymagania dotyczące skalowalności, wymagania dotyczące dostępności i wymagania dotyczące zabezpieczeń. Te czynniki mogą prowadzić do dalszego rozkładania mikrousługi na dwie (lub więcej) mniejsze usługi lub zrobić odwrotnie i połączyć kilka mikrousług w jeden.

Ważne jest, aby być pragmatycznym i pamiętać, że projektowanie oparte na domenie jest procesem iteracyjnym. W razie wątpliwości zacznij od grubszych mikrousług. Łatwiej jest podzielić mikrousługę na dwie mniejsze usługi niż refaktoryzować funkcje w kilku istniejących mikrousługach.

Diagram mikrousług.

Stosowanie projektu opartego na domenie do aplikacji drona

W przypadku aplikacji firmy Fabrikam wszystkie te usługi znajdują się w istniejącej aplikacji monolitycznej. Po zidentyfikowaniu, gdzie można rozłożyć aplikację na mikrousługi, zamierzają rozpocząć od usługi pakowania.

Usługa związana z pakietami ma obecnie skoncentrowany zespół deweloperski, wykazuje problemy z wydajnością związane ze skalowalnością i jest doskonałym kandydatem do rozpoczęcia dekompozycji aplikacji.