Architektura Hexagonalna [Cebula/Porty i Adaptery] 馃敟馃憤

Architektura Hexagonalna znana te偶 jako Onion Architecture lub Ports & Adapters zosta艂a wymy艣lona przez Alistaira Cockburnai opublikowana w 2005 roku. Jej celem jest unikni臋cie znanych pu艂apek strukturalnych w OOP jak np. zale偶no艣ci mi臋dzy wartswami czy te偶 wplatanie kodu odpowiedzialnego za GUI do warstwy logiki biznesowej. Ma ona na celu stworzenie lu藕no powi膮zanych komponent贸w aplikacji, kt贸re mo偶na 艂atwo po艂膮czy膰 za pomoc膮 port贸w i adapter贸w. To sprawia, 偶e komponenty s膮 wymienialne na ka偶dym poziomie i u艂atwia automatyzacj臋 test贸w.


Cze艣膰聽馃檪

To jest ju偶 trzeci wpis z mini-serii blog贸w聽o architekturach aplikacyjnych. W poprzednich wpisach mog艂e艣 przeczyta膰 o

W dzisiejszym artykule dowiesz si臋:


Czym jest architektura hexagonalna

Celem architektury hexagonalnej jest umo偶liwienie, aby aplikacja kt贸r膮 rozwijamy by艂a traktowana tak samo przez u偶ytkownik贸w, programy zewn臋trzne, testy czy te偶 skrypty. Dodatkowo ma ona umo偶liwia膰 rozw贸j i testowanie aplikacji w oderwaniu od zewn臋trznych zale偶no艣ci (baza danych / zewn臋trzne API).

Architektura hexagonalna w centrum aplikacji stawia na przypadki u偶ycia i domen臋 – to te偶 jest pow贸d dlaczego sprawdza si臋 ona dobrze z DDD. Warto zauwa偶y膰, 偶e ten styl architektoniczny jest przeciwny architekturze wartstwowej – tutaj zale偶no艣ci s膮 kierowane do 艣rodka domeny a nie jak w przypadku warstw od g贸ry do do艂u.

 

Nazwa architektury wzi臋艂a si臋 z efektu wizualnego jaki przedstawia hexagon – wi臋cej o tym przeczytasz w artykule Alistair’a Cockburn’a, tw贸rcy architektury:

The hexagon is not a hexagon because the number six is important, but rather to allow the people doing the drawing to have room to insert ports and adapters as they need, not being constrained by a one-dimensional layered drawing. The term 鈥樷檋exagonal architecture鈥欌 comes from this visual effect.


Jak wygl膮da struktura hexagonu

Hexagon sk艂ada si臋 z trzech kluczowych element贸w: domeny (core), port贸w i adapter贸w. Je偶eli spojrzymy na hexagon zaprezentowany na rysunku powy偶ej mo偶na te偶 zauwa偶y膰, 偶e nasz core (domena i przypadki u偶ycia) u偶ywaj膮 port贸w – czyli domena wie na co dany port pozwala, np. zapis u偶ytkownika ale nie wie jak to si臋 stanie. I do tego w艂a艣nie s艂u偶膮 adaptery. Aplikacja mo偶e mie膰 np. prawdziw膮 baz臋 danych, kt贸ra rzeczywi艣cie zapisze u偶ytkownika w bazie ale mo偶e to te偶 by膰 hashmapa, kt贸ra po restarcie aplikacji nie b臋dzie ju偶 niczego pami臋ta膰.

Porty dziel膮 si臋 na wej艣ciowe i wyj艣ciowe. Wej艣ciowe to te, kt贸re steruj膮 nasz膮 logik膮 np. GUI, gdzie u偶ytkownik wywo艂uj臋 dan膮 akcj臋. Wyj艣ciowe s膮 u偶ywane (sterowane) przez logik臋 biznesow膮. Tutaj najlepszym przyk艂adem s膮 bazy danych i zewn臋trzne API. Aplikacja musi porozumie膰 si臋 z jakimi艣 zewn臋trznymi komponentami i w tym celu u偶ywa w艂a艣nie port贸w wyj艣ciowych.

Domena

S膮 to nasze obiekty domenowe. Ich implementacja powinna by膰 na tyle jasna, 偶eby nawet kto艣 nie techniczny m贸g艂 podej艣膰 i powiedzie膰 ok, rozumiem co tu si臋 dzieje. Obiekty domenowe nie powinny mie膰 偶adnych zewn臋trznych zale偶no艣ci. Domena opisuje jak co艣 zrobi膰.

Przypadki u偶ycia

To klasy, kt贸re obs艂uguj膮 konkretne problemy biznesowe. Jest to faktyzcna warto艣膰 dla biznesu, kt贸ra rozwi膮zuje ich problem. Przypadki u偶ycia mog膮 zawiera膰 wszystkie niezb臋dne walidacje i logik臋 regu艂 biznesowych, kt贸re s膮 specyficzne dla konkretnego przypadku u偶ycia (dlatego te偶 nie mog膮 by膰 implementowane w obiektach domeny) a nast臋pnie deleguj膮 prac臋 do domeny. Use case’y nie s膮 zale偶ne od zewn臋trznych komponent贸w, natomiast je偶eli potrzebuj膮 czego艣 z zewn膮trz (np. pobranie u偶ytkownika) to tworz膮 do tego port (albo u偶ywaj膮 istniej膮cego). Przypadki u偶ycia m贸wi膮 co zrobi膰.

Porty wej艣ciowe i wyj艣ciowe

Porty mo偶esz sobie wyobra偶a膰 dok艂adnie tak jak porty w komputerze, np. USB. Nie jest wa偶ne czy pod艂膮czysz urz膮dzenie firmy X czy Y – oba powinny dzia艂a膰.

W architekturze hexagonalnej komunikacja do i z aplikacji odbywa si臋 przez porty. Port wej艣ciowy b臋dzie zazwyczaj interfejsem, kt贸ry jest implementowany przez konkretny przypadek u偶ycia. Podobnie jest z portem wyj艣ciowym – to r贸wnie偶 b臋dzie interfejs. Tym razem jednak przypadek u偶ycia b臋dzie go u偶ywa艂 – a nie tak jak w przypadku portu wej艣ciowego implementowa艂.

Dzi臋ki portom wej艣ciowym i wyj艣ciowym mamy bardzo wyra藕ne miejsca, w kt贸rych dane wchodz膮 i wychodz膮 z naszego systemu, u艂atwiaj膮c rozumowanie na temat architektury.

Adaptery

Adaptery tworz膮 zewn臋trzn膮 warstw臋 architektury hexagonalnej. Nie s膮 cz臋艣ci膮 rdzenia, ale wchodz膮 z nim w interakcj臋. Adaptery r贸wnie偶 dzielimy na dwie grupy: wej艣ciowe i wyj艣ciowe. Wej艣ciowe (lub steruj膮ce) wywo艂uj膮 porty wej艣ciowe, aby co艣 zrobi膰 w aplikacji – w ko艅cu wywo艂uj膮 konkretny przypadek u偶ycia. Wyj艣ciowe (sterowane) s膮 natomiast wywo艂ywane przez przypadki u偶ycia.

Adaptery u艂atwiaj膮 wymian臋 okre艣lonej warstwy aplikacji, np. zmiana bazy danych na inn膮. Wystarczy napisa膰 tylko nowy adapter.


Wady i zalety architektury

Zalety:

    • testowalno艣膰
    • rozwijalno艣膰 i utrzymanie
    • wymiana technologii

Wady:

    • trudniejsza nawigacja po kodzie 藕r贸d艂owym – musimy ogarnia膰 co, gdzie jest u偶ywane
    • wiele adapter贸w = wiele test贸w

Podsumowanie

W tym kr贸tkim wpisie chcia艂em przedstawi膰 Ci ide臋 architektury hexagonalnej. Je偶eli czyta艂e艣 wcze艣niejsze artyku艂y to zapewne ju偶 wiesz, 偶e u偶ycie konkretnej architektury zale偶y od tego czego chce biznes. W przypadku architektury hexagonalnej dobrym wyborem jej zastosowania wydaj膮 si臋 by膰 projekty o zmiennej i z艂o偶onej logice biznesowej. Natomiast zastosowanie jej w CRUD-ach b臋dzie zdecydowanie przesad膮 i przerostem formy nad tre艣ci膮. Zamiast upro艣ci膰 zrozumienie, mo偶esz je tylko niepotrzebnie skomplikowa膰.

殴r贸d艂a:


Za tydzie艅

Moja lista todo robi si臋 coraz d艂u偶sza… jednak zanim zaczn臋 j膮 czy艣ci膰 (mo偶e powinienem pisa膰 2 artyku艂y tygodniowo) chcia艂bym doko艅czy膰 seri臋 o architekturach aplikacyjnych. Dlatego te偶 za tydzie艅 opiszemy popularn膮 architektur臋 mikroserwis贸w.

5 1 vote
Article Rating
Subscribe
Powiadom o
guest
0 komentarzy
Inline Feedbacks
View all comments