Zasada zależności
Clean architecture
nie jest sam w sobie wzorcem architektonicznym lecz propozycją na organizację architektury aplikacji w taki sposób, aby różne obszary oprogramowania były łatwo wymienne, a projekt mógł zostać w całości zaadaptowany w innym środowisku uruchomieniowym bez względu na wykorzystywany framework (np. spójny kod dla aplikacji mobilnej i internetowej). Kod dzielony jest na warstwy
przypominające koncentryczne okręgi
zgodnie z zasadą, że warstwy wewnętrzne
nie wiedzą nic o warstwach zewnętrznych
, a co za tym idzie nie posiadają do nich zależności
. Innymi słowy zależności kodu źródłowego mogą wskazywać tylko do wewnątrz. Dotyczy to każdej jednostki kodu tzn. klasy, funkcji, zmiennej itd. Okręgi reprezentują różne obszary oprogramowania, gdzie zewnętrzne koła są mechanizmami niskiego poziomu, a wewnętrzne zasadami wysokiego poziomu. Im głębsza warstwa tym większy poziom abstrakcji. Przekraczanie granic bez naruszania zasady zależności wartwy możliwe jest za pomocą inwersji zależności
(dependency inversion
) realizowanej przy użyciu różnych technik programistycznych (np. polimorfizm
).
Warstwy
W klasycznym podejściu można wyróżnić cztery warstwy: Entities
, Use Cases
, Interface Adapters
, Framework and Drivers
. Jednakże nie jest to ogólna i jedyna słuszna propozycja. Podział oprogramowania na warstwy zależy od środowiska, wielkości i złożoności aplikacji, postawionych wymagań oraz kalkulacji kosztów i zysków. Równie dobrze może się okazać, że optymalna implementacja realizowana jest w oparciu inną liczbę okręgów. Warstwa Entities
to reguły biznesowe wspólne dla wszystkich aplikacji w projekcie. Mogą to być obiekty z metodami czy też zbiory struktur danych i funkcji. Warstwa Use Cases
zawiera reguły biznesowe specyficzne dla danej aplikacji. Implementuje przypadki użycia systemu, które sterują przepływem danych między podmiotami. Warstwa Interface Adapters
jest zestawem adapterów odpowiedzialnych za konwersje danych z warstw Use Cases
i Entities
do zewnętrznych agentów. To tutaj przeważnie znajdują się klasy implementujące architekturę aplikacji (np. View
, Presenter
, Controller
). Warstwa Framework and Drivers
składa się z różnych zewnętrznych bibliotek, sterowników i narzędzi. W tym miejscu pojawiają się wszystkie szczegóły zewnętrznych wywołań, które są przekazywane do kolejnych wewnętrznych okręgów.
Zastosowanie
Zastosowanie dowolnej architektury systemu pomimo różnic posiada jeden wspólny cel, podział odpowiedzialności i zagrożeń poprzez rozdzielenie oprogramowania na warstwy. Clean Architecture
wpisuje się w ten trend i podobnie jak inne architektury jego użycie dostarcza wielu korzyści. Pozwala na tworzenie systemów niezależnych od framework dzięki czemu biblioteki moga być wymienne i traktowane jako narzędzia. Ułatwia testowanie reguł biznesowych ze względu na ich separacje od interfejsu użytkownika i źródeł danych. Ponadto umożliwia zmianę interfejsu użytkownika oraz źródeł danych bez dokonywania modyfikacji w pozostałych obszarach kodu. Clean Architecture
nie jest związany z żadną konkretną architekturą w związku z czym może zostać zaadaptowany do większości wzorców architektonicznych takich jak MVC
, MVP
, MVMM
, MVI
.
Android
Jedną z najpopularniejszych praktyk realizacji Clean Architecture
dla Android
jest wyróżnienie trzech warstw: Presentation
, Domain
, Data
. Warstwa Presentation
zawiera interfejs użytkownika oraz jego obsługę, Domain
posiada klasy danych i definicję przypadków użycia natomiast Data
składa się z repozytoriów i zewnętrznych źródeł danych. Odwołując się do klasycznej definicji Clean Architecture
możliwe jest zastosowanie jeszcze szerszego podziału poprzez wyłączenie m.in. przypadków użycia z Domain
do osobnej warstwy Use Cases
oraz właściwych źródeł danych do warstwy Framework
.
Przykład
Aplikacja Filmhead umożliwia zarządzanie prywatną listą filmów użytkownika. Filmy mogą zostać dodane do listy obserwowanych, natomiast te obejrzane mogą być ocenione. Projekt posiada dedykowane aplikacje w wersji przeglądarkowej
oraz na urządzenia z systemem Android
. Z uwagi na zachowanie spójności działania aplikacji na wszystkich platformach oraz współdzielenie części kodu zdecydowano się na zastosowanie Clean Architecture
w wariancie pięciu warstw: Presentation
, Use Cases
, Domain
, Data
, Framework
. W przypadku aplikacji mobilnej należy podjąć także decyzję o wyborze wzorca architektonicznego (np. MVP
).
W warstwie Domain
definiowane są modele danych wykorzystywane przez kolejne warstwy. Klasyczny Clean Architecture
proponuje posiadanie jednej reprezentacji modelu danego bytu dla każdej warstwy w celu całkowitej niezależności warstw od modeli wewnętrznych. Jednakże w wielu przypadkach może się to wiązać z przerostem formy nad treścią.
Warstwa Data
odpowiedzialna jest za definicję repozytoriów (Repositories
) realizujących logikę biznesową żądań poprzez wywołanie odpowiednich operacji na deklarowanych źródłach danych (Sources
).
Warstwa Use Cases
konwertuje akcje i zdarzenia użytkownika oraz systemu do żądań delegowanych do kolejnych wewnętrznych warstw.
Warstwa Framework
wykorzystuje specyficzne zewnętrzne zależności (np. biblioteka systemowa, wybrany framework) implementując szczegóły realizacji przypadków użycia.
Warstwa Presentation
odpowiedzialna jest za prezentację i obsługę interfejsu graficznego użytkownika. W tym miejscu poza widokiem definiowane są klasy architektury (np. MVP
).