Zwiększ przejrzystość swojego monolitu dzięki ograniczonym kontekstom

sprawdź wideo z tego wykładu z ElixirConf 2017 poniżej

Aplikacje monolityczne są świetne, gdy zaczynasz budować swoją firmę, ale w miarę upływu czasu stają się trudne do utrzymania. Te kody, w miarę wzrostu, łatwo stają się dużymi kulami błota.

Indiana Jones Rock

podczas budowania dużych aplikacji w frameworkach, takich jak Rails, zasady projektowania konwencyjnego nadkonfiguracji, które sprawiły, że Rails cieszyły się z używania, zaczynają przeszkadzać, gdy aplikacja rośnie w zasięgu. Możesz odczuwać te same bóle, jak również, jeśli:

  • Refaktoryzacja jest trudna i żmudna, Ponieważ Metody i klasy zależą od zbyt wielu innych klas
  • masz ciągle rosnącą listę obiektów biznesowych, które są trudne do utrzymania w głowie. W rzeczywistości wydaje się, że nikt nie jest w stanie zrozumieć systemu jako spójnej całości
  • zmiana kodu w jednym obszarze kodu prowadzi do nieoczekiwanych i niezamierzonych skutków ubocznych w innych obszarach kodu, ponieważ łatwo jest wywołać globalne usługi i Obiekty

w naszym ostatnim wspólnym czacie omówiliśmy opracowanie wszechobecnego języka wraz z ekspertami biznesowymi i zespołem programistów, aby pomóc zespołowi w ściślejszej współpracy. Dzisiaj zamierzamy na tym skorzystać, wprowadzając nowe narzędzia do projektowania opartego na domenach (DDD). Następnie Przedstawimy nową strukturę folderów dla Twoich aplikacji Rails, przygotowując je na przyszłość, w której Twoja aplikacja będzie mniej powiązana i bardziej spójna. Zaczynajmy!

porozmawiajmy o domenach

kluczową zasadą w DDD jest to, że oprogramowanie, które tworzysz, musi ściśle odzwierciedlać domenę (biznesową) organizacji, która ją buduje. W związku z tym musimy odrobić trochę pracy domowej, aby zrozumieć domenę biznesową Twojego oprogramowania.

domena jest tym, co robi Firma, i kontekstem tego, jak to robi.

wróćmy do naszego przykładu Delorean z poprzedniego postu. W nim firma jest sprzedawana jako Uber dla wycieczek w czasie. Stąd jego” domeną “(“tym co czyni”) jest podróżowanie w czasie. W domenie znajduje się również “jak” tego, jak to robi – współpracując z kierowcami, którzy posiadają Pojazdy Delorean podróżujące w czasie z pasażerami, którzy chcą odbyć podróże w czasie.

aby uzyskać więcej niuansów w domenie biznesowej, DDD wprowadza inną koncepcję, zwaną subdomeną:

subdomena reprezentuje mniejsze grupy lub jednostki firmy, które współpracują na co dzień, aby osiągnąć cele biznesowe.

Delorean jest podzielony na kilka zespołów w firmie. Przyjrzyjmy się dwóm z nich i zobaczmy, za co są odpowiedzialni:

zespół platformy Trip zespół operacji finansowych
misja Projektowanie i obsługa systemów, które wyznaczają trasy podróży i łączą kierowców z pasażerami Zarządzanie systemami, które angażują instytucje finansowe i podmioty przetwarzające Karty kredytowe
obowiązki
  • Połącz pasażerów z kierowcami
  • skieruj kierowcę do następnego miejsca docelowego
  • powiadom pasażerów o przylatujących kierowcach
  • powiadom kierowców o nowych pasażerach
  • przetwarzaj wypłaty dla kierowców
  • utrzymuj systemową historię transakcji w celu przeprowadzenia audytu
  • buduj raporty finansowe
  • przetwarzaj opłaty kartą kredytową dla pasażerów

każda z tych dwóch grup animuje odpowiedzialność biznesową lub subdomenę. Nazwijmy je odpowiednio: Ridesharing Experience i Ecommerce.

teraz mamy ogólną ilustrację biznesu i dwóch jego jednostek, które pomagają mu funkcjonować na co dzień. Domena i subdomena to sposoby modelowania przestrzeni problemowej Twojej firmy-i tego, jak działa, aby spełnić te role. Są szanse, że wykres organizacji firmy będzie ściśle odzwierciedlał subdomeny Twojej firmy. W realnym świecie, granice mogą być mniej jasne-zespoły mogą być odpowiedzialne za wiele, nakładających się subdomen.

wypełnimy ten diagram jeszcze kilkoma subdomenami w biznesie Delorean:

  • subdomena Obsługi Klienta: rozwiązywanie zgłoszeń do obsługi klienta za pośrednictwem poczty e-mail
  • subdomena marketingowa: zarządzanie marketingowymi kampaniami e-mailowymi i kodami kuponów marketingowych
  • subdomena tożsamości: jak system śledzi każdego użytkownika i jego dane identyfikacyjne

ograniczone konteksty w przestrzeni rozwiązań

ten diagram przed nami odzwierciedla teraz cele biznesowe firmy, podzielone na jednostki logiczne, które (miejmy nadzieję) realizują swoje cele w świecie rzeczywistym. Teraz będziemy nakładać systemy programowe, które osiągają te cele na tym diagramie. Te systemy oprogramowania są opisane jako ograniczone konteksty:

Ograniczony kontekst to system, który realizuje cele biznesu w realnym świecie.

każdy z naszych systemów oprogramowania (takich jak usługa internetowa lub aplikacja internetowa), które działają jako konkretne instancje w świecie rzeczywistym, jest uważany za Ograniczony kontekst.

technicznie rzecz biorąc, Ograniczony kontekst w DDD-speak jest konkretną granicą w Twojej domenie, którą może zastosować tylko Twój słowniczek z twojego wszechobecnego języka – chodzi o to, że różne subdomeny mogą mieć konkurencyjne lub sprzeczne definicje terminów. Ten post nie będzie rozwijał niuansów językowych ograniczonego kontekstu. Więcej informacji można znaleźć w wyjaśnieniach Martina Fowlera dotyczących kontekstów ograniczonych.

teraz tak się składa, że w Delorean wszystkie te subdomeny są zaimplementowane w jednym systemie-jedna wielka kula szyn błotnych Monolith. Narysujemy niebieskie pole wokół subdomen, których funkcje są realizowane przez system oprogramowania. W tym przypadku zaczniemy od wspomnianego już Rails monolith:

ponieważ jest to monolit, w zasadzie robi wszystko-a więc tutaj, pożera wszystkie inne subdomeny na diagramie.

nie zapominajmy – mamy kilka innych systemów oprogramowania, których nie modelowaliśmy tutaj. A co ze wszystkimi przyjemnymi integracjami stron trzecich, z których korzysta firma? Są to również systemy programowe. Narysujemy je jako niebieskie pudełka.

przy okazji-narysowaliśmy tu mapę kontekstową-diagram łączący cele biznesowe z konkretnymi implementacjami systemów oprogramowania. Jest to przydatne do oceny położenia terenu systemów oprogramowania i wizualizacji zależności między zespołami.

teraz jest to rozsądne i czyste, ale żyjemy w prawdziwym świecie, a prawdziwe oprogramowanie rzadko wychodzi spójnie i spójnie. Jeśli zbudowałeś aplikację Rails zgodnie z jej gotowymi konwencjami, wewnętrznie nie ma w niej grup niezbędnych do wizualizacji aplikacji w jej składowych komponentach. W rzeczywistości kod Delorean wygląda mniej więcej tak:

chodzi o to, że Rails nie wymusza żadnych ograniczeń organizacyjnych na naszych systemach oprogramowania-co oznacza, że logiczne jednostki biznesowe (nasze subdomeny) sugerujące oddzielone interfejsy – nie są zmaterializowane w kodzie, co prowadzi do zamieszania i rosnącej złożoności z biegiem lat.

wielki pomysł: Uporządkuj kod Rails w Moduły według subdomeny biznesowej

mimo że Twoje klasy Ruby w Twojej aplikacji prawdopodobnie żyją w globalnej przestrzeni nazw, można je łatwo połączyć w Moduły. Naszym celem jest stworzenie logicznych grup kodu domeny, które można wyizolować w samodzielne komponenty.

jednym z celów projektów opartych na domenach jest mapowanie jeden do jednego z subdomen do ograniczonego kontekstu.

OK, co to znaczy? Przejdźmy do kilku zaleceń wraz z przykładami.

Odwróć struktury folderów w płaskie grupowanie zorientowane na domenę

możesz pamiętać, że przestrzeganie Konwencji Rails prowadzi nas do hierarchii folderów, które grupują klasy według ról:

przenieśmy wszystko do nowej struktury katalogów: grupujmy funkcjonalność według domeny. Zaczniemy od pierwszej odmiany, którą nazwałbym grupowaniem zorientowanym na domenę płaską.

Modulizuj klasy

następnie będziesz chciał modulizować klasy z tego, co były wcześniej. Ponieważ Klasa Sterownika mieści się w domenie współdzielenia przejazdów, dodamy ją do modułu współdzielenia przejazdów:

będziesz chciał to zrobić dla każdej klasy, którą przeniesiesz do płaskiej struktury katalogów app/domains.

odwoływanie się do powiązanych modeli według pełnej nazwy klasy

dodatkowo musisz zmienić powiązania modelu ActiveRecord, aby odnosić się do klasy według pełnej, modulizowanej ścieżki:

Informuj Kontrolery na bieżąco o tym, gdzie znaleźć ich nowo modulizowane widoki

musisz również wstawić ten mały bit, aby trasy z kontrolera wiedziały, gdzie szukać widoków:

oto fajna sprawa: nie musisz przenosić całego kodu na raz. Możesz wybrać jedną małą domenę w aplikacji, najbardziej dojrzały obszar kodu lub obszar, który najlepiej rozumiesz, i zacząć przenosić swoje obawy do jednego folderu domeny, pozostawiając istniejący kod w spoczynku, dopóki nie będzie gotowy do przeniesienia.

teraz zrobiliśmy kilka małych kroków w celu osiągnięcia przejrzystości architektonicznej w naszej aplikacji. Jeśli spojrzymy teraz, nasze modułowe struktury folderów pomogły nam pogrupować nasz kod w ten sposób:

pod maską nasza aplikacja może wyglądać bardziej tak:

co dobrze działa z takim podejściem?

  1. w każdym katalogu plików jest mniej szumu – grupując pliki według specyfiki domeny, znajdujemy naturalny punkt organizacyjny
  2. encje, które pozostają w każdym folderze domeny, są wysoce spójne-najprawdopodobniej naturalnie komunikują się ze sobą i pojawiają się naturalnie ze sobą
  3. encje, które nie należą do siebie, są teraz oddzielone (luźniej połączone)
  4. jeśli masz zespoły inżynierskie, które pracują zgodnie z obowiązkami subdomeny, ci inżynierowie mogą teraz pracować w bardziej uproszczony, odizolowany sposób. Luźniejsze sprzężenie pozwala tym zespołom wprowadzać zmiany z pewnością, że nie wprowadzą regresji ani nie połączą konfliktów z powrotem do bazy kodu
  5. etap jest teraz ustawiony na dłuższą metę, aby rozpocząć przenoszenie każdego z tych folderów domeny do niezależnej usługi oprogramowania (więcej na ten temat w przyszłym poście na blogu)

jeśli chcesz uzyskać dalsze wskazówki dotyczące tej struktury folderów, opracowałem przykładową aplikację, która wyświetla tę zorientowaną na domenę strukturę folderów: http://github.com/andrewhao/delorean. Spójrz i daj mi znać, co myślisz.

czego się nauczyliśmy?

w naszych wspólnych czasach dowiedzieliśmy się o koncepcjach projektowania opartych na domenach wokół domen i subdomen. Nauczyliśmy się wizualizować nasze systemy jako ograniczone konteksty na mapie kontekstu, która pokazała nam obszary systemu, które należą do siebie jako spójne części.

kończąc na praktycznej notatce, zilustrowaliśmy, jak pliki i foldery Rails mogą być “odwrócone” i przekształcone jako grupy domenowe.

w moim następnym poście, będziemy kontynuować naszą dyskusję w nadchodzącym poście na blogu na temat dalszego oddzielenia naszego kodu Rails zorientowanego na domenę ze zdarzeniami domenowymi i ostatecznie udamy się do krainy mikroserwisów.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.