Trzy najczęstsze typy architektury modularnej.

 


Zacznijmy od pytania retorycznego - co to jest moduł, co to jest warstwa a co to jest mikroserwis?

Tu mówimy o modułach i relacji modułów do warstw. Nie interesuje nas to czy są to jednostki podzielone na osobne jednostki wdrożeniowe czy nie, czy ruch odbywa się między nimi po http czy jako wywołania metod na interfejsie zaimplementowanym w innym module. Oczywiście zasada jest prosta - "mniej wiązań" oznacza "lepiej" o ile funkcjonalności są zachowane a wiązania nie są "ciężkie" w znaczeniu takim, że transportują często i duże ilości danych. 

Moduły: Architektura startupowa. 

Zacznijmy zatem od sytuacji takiej. Mamy startup i chcemy wdrażać szybko prosto i budować funkcjonalności przynoszące zysk finansowy a nie architekturę statku kosmicznego. Buduje się więc moduły związane z konkretnymi funkcjonalnościami. Oczywiście czasem wymagają siebie nawzajem. Funkcjonalności będą dopiero poznane w pełni kiedy będą zaimplementowane więc nie narzuca się stylu modułom. Każdy z nich zawiera każdą warstwę (rozumianą jak w architekturze warstwowej), są one trzymane razem, ale dostęp do nich spoza modułu jest niemożliwy. Są tam tylko te warstwy które są sobie potrzebne i tworzymy mniej złożone szkatułkowe struktury relacji między warstwami. Warstwy możemy wymieniać łatwo bo są małe. Nie mamy potrzeby stosowania wszędzie interfejsów i implementacji bo moduły są proste i małe. Każdy obiekt zawiera wewnętrzną logikę związaną ze zmianą stanu i walidacją wewnętrznie. Agregaty grupują obiekty i są granicami transakcji. Stosujemy GRASP i SOLID. Serwisy mogą wykonywać operacje na kilku agregatach w transakcjach łączących konkretne grupy operacji w funkcjonalności bardziej złożone. Czasem stosujemy sagi. Wymiana bazy danych odbywa się stopniowo, moduł po module. Każdy moduł może mieć własne rozwiązanie dla problemów biznesowych, własne zależności i konfiguracje. Każdy może być przeniesiony do osobnej aplikacji. Zmiana języka programowania to pisanie aplikacji moduł po module i przekierowywanie ruchu do nowej aplikacji. Umożliwia to spokojną pracę, jest to raj dla programistów utrzymania którzy działając na określonej funkcjonalności nie muszą znać innych a te których dotykają są dla nich banalnie proste. Zależności między modułami realizowane są jako porty (klienty) i adaptery (serwisy).


Warstwy: Architektura bootcampowa. 

Moduły dzielone warstwowo. Nie odzwierciedlają podziału na funkcjonalności, ale odzwierciedlają stack technologiczny. Robiona przez programistów bez potrzeby zrozumienia biznesu. Aplikacja zaprojektowana idealnie do wymiany bazowych technologii jak np. bazy danych. Niestety dizajn ten sprawdza się tylko w teorii, nie w praktyce. Nigdy nie przetestowany a programiści nie pracowali nigdy przy utrzymaniu - gdyby ktoś testował to wiedziałby że wymiana całej bazy danych na raz dla wszystkich modułów w dużej aplikacji jest jak próba wymiany mózgu. Każda biznesowa operacja jest rozpostarta na każdy moduł i znajduje się w nich śladowa część logiki odpowiedzialnej za działanie technologii w niepokalanej dziewiczej logice pisanej w czystej Javie. Nie zakłada nikt zmiany języka programowania. Wyciąganie transakcji bazodanowego poza moduł bazy danych jest zawsze łamaniem zasady podziału. Często logika znajduje się w klasach służebnych który znajomość jest konieczna gdyż obiekty są czystymi strukturami danych. Proces wejścia w projekt wymaga dokumentacji na poziomie każdej klasy która opisuje mechanizmy walidacji, procesowania określonych zmian. Testowanie możliwe jest jedynie za pomocą testów jednostkowych gdzie jako jednostkę rozumie się klasę a serwis wykonuje jedynie proste mapowania i transformacje zaś prawdziwe operacje delegowane są do klas pomocniczych realizujących logikę biznesową. Ten projekt powinien umrzeć bo będzie źródłem cierpień developerów.


Wiadro: Architektura korporacyjna czyli  wrzucić wszystko i wymieszać. 

Tu zaczyna się orgiastyczna zabawa w dzielenie aplikacji na moduły i łączenie ich by cokolwiek działało. Architekt korporacyjny tworzy obóz koncentracyjny dla developerów i wie że trzeba dzielić by rządzić. Bootcamp guru na haju po konferencji gdzie mówili że "hexagonalna" architektura jest ok i trzeba ją wdrażać więc wrzuca onion. Każda technologia i każda funkcjonalność ma swój moduł. Każdy moduł biznesowy potrzebuje każdego modułu technologicznego i do tego jak wiemy zawsze występują zależności między samymi modułami funkcjonalnymi, które czasem potrzebują siebie nawzajem. Funkcjonalności wszystkich modułów funkcjonalnych spotykają się i mieszają w modułach technologicznych. Bez super ciężkiego IDE nie masz szans na poruszanie się w tym gąszczu. Moduły powstają jak grzyby po deszczu gdyż powstaje kratka z podziału funkcjonalnego i warstwowego. Gdyby podzielić to na mikroserwisy byłby to dystrybuowany monolit. Projekt ma sens jako piekło w którym smażą się źli programiści. Wyciągnięta do modułu bazodanowego baza danych gdyby miała zostać wymieniona (bo przecież po to jest przeniesiona) musiałaby być wymieniona cała na raz i testowanie zmiany musi odbywać się w każdym module. 


Comments