/ We know how

Clean Architecture – zalety tworzenia czystej architektury dla przedsiębiorstwa

Istotą Clean Architecture jest taki dobór architektury i sposobów kodowania systemów, aby zredukować koszty ich wytworzenia, użytkowania, rozwijania i modernizacji w całym cyklu życia. W ten sposób minimalizuje się całkowite koszty posiadania systemu  i jednocześnie maksymalizuje produktywność zespołu programistów. Robert C. Martin, twórca koncepcji Clean Architecture, napisał kiedyś, że „każda organizacja projektująca system, tworzy jego architekturę na wzór struktury komunikacyjnej organizacji”[i]. W tym stwierdzeniu jest dużo prawdy – staranność w projektowaniu i kodowaniu ma ścisły związek z kulturą organizacyjną całej firmy. Prawidłowe wybory na etapie projektu i wysoka jakość pracy programistów powodują, że kod jest łatwy do zrozumienia, rozwijania i utrzymania, a samo wdrożenie przebiega szybko i bezproblemowo. 

 

 

Czym tak właściwie jest Clean Architecture?

 

U podstaw Clean Architecture legło założenie, że sformułowane wymagania biznesowe powinny w minimalnym stopniu mieć związek z konkretną technologią i szczegółami implementacyjnymi. Zatem wszystkie warstwy tworzące strukturę projektu powinny mieć wyraźnie wydzielone zadania i odpowiedzialność, dając się jednocześnie ławo wyizolować od całości rozwiązania. Idąc dalej, Robert C. Martin zaproponował, żeby tak projektować systemy, aby dało się możliwie dużo kodu współdzielić pomiędzy wieloma środowiskami. W jego oryginalnej propozycji można było wydzielić cztery warstwy:

  1. aplikacji,
  2. prezentacji
  3. logiki domenowej/biznesowej

Dwie główne warstwy: prezentacji i logiki domenowej są niezależne od technologii użytej do tworzenia aplikacji i mogą być współdzielone, a warstwy aplikacji i danych są ściśle związane ze środowiskiem uruchomieniowym i używanymi narzędziami. Zatem po ich połączeniu w całość, mamy sytuację, w której można raz napisać logikę domenową, a potem współdzielić ją w aplikacjach mobilnych na iOS i Androida, jak też w systemach webowych i desktopowych.

Wspólną cechą tak zdefiniowanych warstw jest ich niezależność od frameworków, które są traktowane wyłącznie jako narzędzia. Poza tym są one łatwo testowalne, bo logika biznesowa jest oddzielona od trudno testowalnych elementów takich, jak bazy danych, czy interfejsy użytkownika.

W koncepcji Clean Code Architecture warstwa aplikacji jest najmocniej połączona z konkretną technologią i narzędziami. Jej zadaniem jest zapewnienie graficznej oprawy i wizualizacji  danych. Warstwa aplikacji decyduje o tym, jak wyświetlać dostarczone dane i jak reagować na zadania  napływające z warstwy prezentacji. Z jednej strony musi ona zawierać reguły wyświetlania, a z drugiej potrafić informować warstwę prezentacji o wszelkich akcjach użytkownika, który reaguje na pojawiające się dane i zdarzenia.

W warstwę prezentacji wbudowane są mechanizmy sterujące całą aplikacją, poszczególnymi ekranami, reakcjami na działanie użytkownika, czy obsługą danych. W tej warstwie zapadają także decyzje, w jaki sposób obsłużyć dane zadania albo jaką część aplikacji i w jakiej kolejności pokazać użytkownikowi. Interfejsy warstwy prezentacji komunikują się z widokami, ale jest to komunikacja jednokierunkowa – do widoków. Prawidłowe zaprojektowanie warstwy prezentacji wymaga poznania działania realnych procesów biznesowych. Doskonale się do tego nadają rozwiązania klasy Business Process Discovery (BPD).

Warstwa prezentacji może zostać zbudowana z wykorzystaniem jednego z dostępnych wzorców projektowych takich, jak: Model View Controller (MVC)[ii], Model View Intent (MVI)[iii], Model View ViewModel (MVVM), czy Model View Presenter (MVP). Wybór jest sprawą drugorzędną i programiści samodzielnie decydują o wyborze wzorca.

 

 

Clean architecture – najważniejsze pojęcia

 

Czystą architekturę można zwizualizować jako współśrodkowe okręgi odpowiadające poszczególnym warstwom architektury, gdzie w środku znajduje się warstwa najwyższego poziomu. Zatem w centrum mamy logikę domenową i encje, czyli obiekty biznesowe. Warto pamiętać, że logika domenowa lub w nieco węższym pojęciu – biznesowa[iv], dotyczy reguł funkcjonujących w danym obszarze aktywności człowieka. Takie niezmienniki funkcjonują niezależnie od tego, czy powstało jakieś oprogramowanie wykorzystujące tę logikę. Przykładem może być obliczanie np. podatku dochodowego albo proces śledzenia przesyłki do klienta. W tej warstwie swoje odbicie muszą znaleźć także wszystkie istotne procesy biznesowe i przepływy pracy. Do składowych warstwy logiki domenowej, można zaliczyć:

  1. UseCase – składnik, którego zadaniem jest odwzorowanie prawdziwych i realnych wymagań biznesowych oraz dostarczenie warstwie prezentacji dostępu do operacji na danych – np. do pobierania lub modyfikowania wartości poprzez obliczenia. Co ciekawe, UseCase to jedyny sposób wymiany danych pomiędzy warstwą prezentacji a warstwą logiki domenowej.
  2. Model – to zbiór danych uporządkowanych zgodnie z wybranymi regułami, które są wykorzystywane przez logikę biznesową. Modele w tej warstwie mogą się znacząco różnić od modeli z warstwy danych, łącząc np. kilka modeli w jedną całość, w zależności od potrzeb.
  3. Logika – to miejsce w strukturze, które służy do przechowywania wydzielonych klas opisujących skomplikowane przypadki logiki domenowej, a które są rzadziej wykorzystywane. Dzięki temu unika się nadmiernie rozbudowanych UseCase.
  4. DataSource – decydują o miejscu pobierania i zapisywania danych oraz mają dostęp do wszystkich źródeł danych udostępnianych przez warstwę danych. Są one zatem jedynym połączeniem pomiędzy warstwami logiki domenowej i danych. Zadaniem DataSource jest przygotowanie danych do przetwarzania w UseCase.
  5. Mappery – dbają o spójność i kompletność danych dostarczanych przez warstwę danych tak, aby logika domenowa mogła działać bez zarzutu. Mappery często integrują kilka obiektów z różnych źródeł w warstwie danych w celu utworzenia jednego, ale za to zawierającego wszystkie niezbędne z punktu widzenia logiki domenowej dane.

Zadaniem warstwy danych jest zapewnianie dostępu do wszelkich źródeł danych i modeli odwzorowujących te dane. Dostęp do metod zawartych w tej warstwie jest możliwy wyłącznie za pośrednictwem własnych interfejsów. Warto zwrócić uwagę, że warstwa danych jest bardzo silnie związana z platformą i narzędziami wykorzystywanymi przez czystą architekturę systemów IT. Wśród najważniejszych konstrukcji w tej warstwie można znaleźć:

  1. Data Transfer Object (DTO), czyli model do dwukierunkowego przesyłania danych. Są one wykorzystywane tylko w tej warstwie, a z ich usług korzystają mappery lub modele biznesowe, w zależności od kierunku przesyłania danych.
  2. Data – są to miejsca pobierania i zapisywania danych wykorzystywanych w pozostałych modułach systemu. Odpowiednie interfejsy umożliwiają łatwą i szybką wymianę źródeł danych – wystarczy podać odpowiednie obiekty implementujące te interfejsy, aby podmienić dane napływające poprzez Bluetooth na strumień danych z internetu, systemu GPS, czy kamery. Takie zastępowanie źródeł danych najczęściej wykorzystuje się w sytuacji obsługi różnych typów serwerów albo korzystania z danych testowych.

W literaturze na temat Clean Architecture spotyka się także pojęcie adaptera interfejsów, czyli połączenia UseCase z interfejsami systemu i adaptacją danych dla obu sąsiednich warstw.

 

 

Jakie są zalety podejścia Clean Architecture?

 

Najważniejszą i najpoważniejszą zaletą stosowania Clean Architecture jest łatwość utrzymania i rozwijania kodu projektu. Lokalizowanie i naprawianie wszelkich błędów jest w tym podejściu bardzo proste. Już nawet na poziomie nadawania nazw zmiennym, Robert C. Martin zalecał, aby dokładać takiej samej staranności, co z nadawaniem imienia pierwszemu dziecku. Długa opisowa nazwa jest lepsza niż krótka i enigmatyczna, a jeszcze lepsza niż długi opisowy komentarz. Dzięki temu prostsze staje się zarządzanie zmianą. Podejście Clean Architecture, dzięki małym klasom z wydzielonymi odpowiedzialnościami, pozwala szybko i łatwo modyfikować kod pod kątem nowych wymagań. Podobnie wygląda dodawanie nowych funkcjonalności bez obawy o konsekwencje w pozostałych częściach projektu.

Wspomniana duża liczba małych klas i interfejsów pozwala na lepsze i staranniejsze testowanie każdego fragmentu kodu, a to redukuje dług technologiczny[v], który z reguły powstaje w sytuacji zwiększonej presji czasu i wymagań biznesowych. Wszystko to przekłada się na niższe koszty zarządzania projektem i późniejszą eksploatację i rozwój aplikacji.

 

 

Jakie są wady podejścia Clean Architecture?

 

Oczywiście zły kod można zawsze wyczyścić i poprawić, ale z reguły jest to bardzo kosztowne i co najgorsze – czasochłonne, a czas to jedyny zasób, którego nie można odtworzyć.

Stosując reguły Clean Architecture trzeba pamiętać, ze wymagają one ok. 10%  dodatkowego zaangażowania na planowanie i pisanie kodu. Do wad tego podejścia wypada zaliczyć także wysoki próg wejścia – aby stosować czystą architekturę systemów IT potrzebna jest po prostu zaawansowana wiedza. Dla wielu praktyków duża liczba małych klas i interfejsów oznacza także dużo plików do zarządzania, co przy większej skali projektu może być osobnym wyzwaniem. Zupełnie osobnym zagadnieniem jest obszar zastosowań Clean Architecture – nie do każdego typu aplikacji będzie to odpowiednie podejście, czasami lepsze może się okazać RAD (Rapid Application Development), szczególnie przy szybkim tworzeniu prototypów lub aplikacjach o znanym już cyklu życia, z jasnym i dobrze zdefiniowanym celem. Brak daleko posuniętej uniwersalności także można zaliczyć do słabości tej koncepcji.

 

 

W jakich projektach najbardziej sprawdzi się Clean Architecture?

 

Clean Architecture to działo większego kalibru. Zatem warto je wytaczać do projektów o odpowiedniej skali, gdzie wymagana jest wysoka wydajność i zróżnicowana funkcjonalność. Przy zbyt małych zadaniach nakłady czasowe na dodatkowe prace są po prostu zbyt duże. Trzeba być jednak ostrożnym – czasami z czegoś małego może się wykluć całkiem duża i pokaźna aplikacja. Wczesne zastosowanie Clean Architecture pozwala uniknąć powstania znacznego długu technologicznego, który na długo może utrudnić rozwijanie obiecującego projektu. Warto zatem wziąć sobie do serca uwagi Roberta C. Martina, który stwierdził, że czysty kod zawsze wygląda tak, jakby został napisany przez kogoś, kogo ten kod obchodzi.

[i] Robert C. Martin, Clean Code: A Handbook of Agile Software Craftsmanship, Financial Times Prentice Hall; Edycja I, (14 sierpnia 2008).

[ii] https://cycle.js.org/model-view-intent.html#model-view-intent-what-mvc-is-really-about

[iii] https://cycle.js.org/model-view-intent.html#model-view-intent

[iv] http://tymoteuszkestowicz.com/2019/01/logika-biznesowa-to-nie-jest-logika-aplikacji/

[v] https://goodpoint.blog/dlug-technologiczny-czym-nim-zarzadzac/