Co to jest dobra architektura ?
Kiedy możemy powiedzieć, że architektura naszego systemu jest dobra? Czy da się znaleźć rozwiązanie, które będzie się dobrze sprawdzać w wielu systemach przez długi czas? Dobre określenie tego czego się szuka jest kluczowe dla sukcesu poszukiwań. Dlatego warto zastanowić czego oczekujemy od architektury naszych systemów i jakich kryteriów użyć, żeby określić czy jest ona faktycznie dobra.
Dobra, ale do czego i dla kogo ?
Rozważania nad architekturą zaczynać powinniśmy zawsze od zadania sobie pytania, co to w ogóle jest dobra architektura. Pytanie to nie ma prostej odpowiedzi, gdy zaczniemy skupiać się na takich aspektach jak skalowalność, testowalność, czytelność, etc. Które cechy wybrać, które z nich są ważniejsze, a które mniej ważne? Jeżeli tak zawęzimy nasze podejście to nadal brakuje nam jasnego kryterium.
Dlatego lepiej określić dobrą architekturę jako tę, która najlepiej wspiera realizowanie założonych celów. Jeżeli naszym celem jest stworzenie systemu, który musi być przygotowany na obsługę gwałtownie rosnącego ruchu, to dobra jest taka architektura, która wspiera skalowalność. Jeżeli jednak nie mamy takich potrzeb, to architektura wspierająca skalowanie będzie najprawdopodobniej jedynie zbędnym ciężarem.
Punktem wyjścia powinny być więc zawsze cele jaki sobie stawiamy, a nie absolutne pojęcie dobrej architektury. Różne środki architektoniczne to tylko narzędzia pozwalające zbudować system. Dlatego należy skupić się na doborze właściwego narzędzia do zadania jakie przed nami stoi.
Standaryzacja za wszelką cenę
Bardzo istotne jest też, żeby nie aplikować jednego rozwiązania wszędzie, tylko dlatego aby osiągnąć jednolite podejście. Jeżeli CQRS jest gdzieś potrzebny, to stosujmy go, ale tylko tam gdzie ma to sens. Nie róbmy osobnego stosu Read i Write tam, gdzie jest tylko prosty CRUD. Jeżeli potrzebujemy gdzieś architektury warstwowej, albo porów i adapterów, to ok, ale być może w innej części systemu jedna warstwa (sic!) będzie najlepszym rozwiązaniem.
Te różne style architektoniczne da się wbrew pozorom dość łatwo łączyć przy zachowaniu dobrej czytelności. Muszą być jednak jasko określone cele i idące za nimi kryteria, kiedy należy stosować jakie rozwiązanie.
Jednolitość jest istotna, ale tylko w obrębie danego rozwiązania architektonicznego. Jeżeli stosujemy Hexagonal Architecture, to zawsze porządkujmy kod w ten sam sposób, aby zwiększyć czytelność. Nie wtłaczajmy jednak w tę strukturę CRUDa, bo czytelność zostanie w ten sposób zmniejszona, a nie zwiększona.
Drivery architektoniczne
Wróćmy jeszcze do celów jaki stawiamy naszemu systemowi. Z czego one wynikają ? Przede wszystkim z wymagań funkcjonalnych, które formułują potrzeby biznesu. Oprócz tego jest jednak wiele wymagań poza-funkcjonalnych, które mają równie istotny wpływ na architekturę. Nasz system nie jest też tworzony w próżni. Wokół istnieje świat zewnętrzny dostarczający nam technologii, możliwości organizacyjnych, ale również nakładający szereg ograniczeń jak choćby wymogów prawnych lub uwarunkowań rynku pracy. Wszystkie te czynniki określane są często jako drivery architektoniczne.
Czynników tych może być bardzo wiele i nie wszystkie są oczywiste, przez co łatwo niektóre pominąć. Klasycznymi przykładami są: skalowalność, wydajność, wymogi bezpieczeństwa. Jest ich jednak znacznie więcej. Jak często zastanawiamy się nad takimi kwestiami jak: aktualne i pożądane kompetencje zespołu, określony poziom rotacji, czy struktura organizacyjna przedsiębiorstwa ?
Z driverami architektonicznymi jest jeszcze jeden problem. Są zmienne. Statyczne ich ujęcie na początku projektu i opisanie w dokumentacji nie jest więc najlepszym podejściem. Tak jak powinniśmy zwinnie podchodzić do wymagań funkcjonalnych, tak samo powinniśmy podchodzić do wymagań poza-funkcjonalnych. Jest to pogoń za celem, który ciągle zmienia położenie. Stąd ciągły refactoring jest konieczny również w obszarze architektury. Jest on oczywiście o wiele droższy, dlatego warto zainwestować czas w przemyślane wybory, które nie zamkną przed nami możliwości korekty raz wybranego kierunku.
Wnioski
Wszystkie te aspekty należy brać pod uwagę określając co to jest dobra dla nas architektura. To one wyznaczają cele jakie powinniśmy realizować, aby system spełniał oczekiwania tych, dla których jest tworzony. „Spełniał” a nie „spełnił”, gdyż jest to proces ciągły wymagający stałej uwagi. Narzędzia architektoniczne powinny być tak dobrane, aby maksymalnie ułatwiać to zadanie.
Architektura będzie dobra jeżeli będzie realizowała nasze cele i to nie tylko przy pierwszym wdrożeniu, ale przez cały czas życia systemu.
Seria – Architektura nie musi być kosztowna
Zapraszam do lektury pozostałych postów z tej serii:
Marcin Markowski
Architekt, trener, zwolennik podejścia Software Craftsmanship i ścisłej współpracy z biznesem. Specjalizuje się w modelowaniu opartym o Domain Driven Design i projektowaniu architektury systemów.
Zaczynał od consultingu biznesowego, później przeszedł do IT. Pracował zarówno nad systemami „enterprise”, jak i tworzył od podstaw rozwiązania dla małych firm. Próbował wejść w świat startupów z własnym produktem. Ostatecznie został jednak w IT, gdzie działa jako konsultant i trener.