Marcin Markowski - 28.02.2019

Dobra architektura nie musi być kosztowna - wstęp

Dobra architektura kojarzy się zwykle z bardzo dużym wysiłkiem przy starcie projektu. Czy jednak musi tak być? Czy nie da się tego zrobić lekko i rozwijać architektury wraz z rozwojem potrzeb projektu? Co tak naprawdę sprawia, że architektura kojarzy się z ogromem pracy? Warto odpowiedzieć sobie na te pytania, bo system nie może nie mieć architektury.

Pytania z placu boju

Przecież architektura to to, co trudno zmienić. Skoro tak to trzeba mieć wszystko dobrze zaprojektowane od początku, później koszt zmiany będzie zbyt duży.

Określanie architektury jako tego co trudno zmienić jest sensownym podejściem. Dobrze nakierowuje ono na wagę wyborów architektonicznych. Nie znaczy to jednak, że trzeba zrobić wszystko od razu, żeby później nie musieć nic zmieniać. Takie podejście sprawdziłoby się tylko w projektach, w których nie ma żadnych niewiadomych i można z góry ustalić optymalne rozwiązania. Brzmi jak stary dobry Waterfall … Problem w tym, że tak jak Waterfall podejście to sprawdza się, delikatnie mówiąc, dość rzadko. Zwykle niewiadomych jest jednak znacznie więcej niż wiadomych.

No właśnie, więc nie zajmujmy się architekturą na początku, to nie jest za bardzo Agile ani Lean. Ona się później sama wyłoni.

Tak prosto niestety nie będzie. Liczenie na to, że coś samo magicznie się zrobi, raczej nie przyczyni się do sukcesu całego przedsięwzięcia. Kluczowe jest ustalenie czego spodziewamy się od naszej architektury i określenie na tej podstawie, co powinniśmy zrobić od razu, a z czy możemy poczekać. Czekanie jest zawsze spowodowane brakiem wystarczającej wiedzy, lub środków. Czekamy więc aż do momentu ich zdobycia, nie dłużej, ale i nie krócej.

Rzadko kiedy jest jednak tak, że nie wiemy w danej kwestii zupełnie nic. Najczęściej wiemy na tyle dużo, żeby określić możliwe rozwiązania, kierunki rozwoju i czynniki od których to będzie zależało. Taka wiedza zwykle wystarcza do przygotowania się na te ewentualności właśnie przez zastosowanie dobrej architektury. Dobrej znaczy w tym momencie tyle co odpowiednio elastycznej, tam gdzie spodziewamy się zmian i prostej do wdrożenia już na starcie.

A co z jednolitym stosem technologicznym i zasadami, których wszyscy będą się trzymać? Bez nich każdy będzie używał innych rozwiązań. Potrzebujemy sprintu zerowego, albo nawet kilku, żeby to wszystko poustawiać.

Jednolitość nie jest wartością absolutną, nie jest też ostatecznym celem naszej architektury. Jednolitość zawsze czemuś służy i to od tego zależy, czy warto o nią walczyć i w jakiej skali. Rzadko kiedy niezbędne jest ujednolicenie wszystkiego i ustalenie standardów na każdą okoliczność obowiązujących wszędzie. Kluczowe jest uchwycenie tego co jest good enough i zrezygnowanie z perfekcjonizmu.

No dobra, ale co z warstwami, portami i adapterami, …? Bez nich nie da się przecież zrobić dobrej architektury, a są one dużym narzutem, bo trzeba tworzyć mnóstwo klas i mapowań.

Czasami warstwy faktycznie są zbędnym narzutem, np. w przypadku CRUDa. Wtedy śmiało możemy zmieścić wszystko w jednej warstwie.

Tam gdzie warstwy, porty i adaptery, czy jakiekolwiek tego typu rozwiązania, coś nam dają, koszt ich wprowadzenie jest zwykle nieporównywalnie mały z korzyściami. Warstwy muszę jednak wspierać określone cele, takie jak testowalność, możliwość oddalenia wyborów technologicznych, łatwa separacja od systemów zewnętrznych. Warstwy będące jedynie technicznymi abstrakcjami robionymi na wszelki wypadek, gdyby kiedyś chciało się wymienić jakąś technologię są całkowicie bez sensu. Sytuacje takie zdarzają się rzadko, a zależności w systemie zwykle i tak nie pozwolą na wymianę całej warstwy bez istotnego przebudowania systemu.

A co z wyborami technologii? Jakiś inicjalny wybór musi przecież być dokonany. Trzeba odpowiednio przygotować całe środowisko, bazy danych, systemy kolejkowe i całą resztę.

To wcale nie jest takie oczywiste. Wybory technologiczne lepiej jest odroczyć do rozwiązania problemów biznesowych. Do tego właśnie przydają się warstwy, czy porty i adaptery. Później przychodzi czas na wybór technologii, ale na początku i tak lepiej stosować minimalny ich zestaw, a bardziej złożone wprowadzać jeżeli faktycznie jest taka potrzeba.

Nie chcemy znowu wpaść w monolit. Podział na małe, niezależne części to przecież mikroserwisy. Wiemy z czym to się wiąże: asynchroniczność, akcje kompensujące, service discovery, circut breaker, … Wdrożenie tego wszystkiego zajmie dużo czasu.

Niekoniecznie. Mikroserwisy to architektura wdrożeniowa. Istotna jest modularność, a nie to jak system będzie wdrażany. Można ją osiągnąć równie dobrze w ramach monolitu, bez ponoszenia na starcie wszystkich kosztów związanych z mikroserwisami. Koszty te warto ponieść dopiero, jeżeli są one uzasadnione faktycznymi potrzebami.

No dobra, ale w systemie jest zawsze mnóstwo bardzo prostych obszarów. Stosowanie do nich wszystkich tych technika na 100% będzie przerostem formy nad treścią.

Tu wracamy znowu do standaryzacji. Nie każdy obszar systemu musi mieć identyczną architekturę. Każdy powinien mieć najprostszą jaka wspiera stawiane przed nim cele.

No dobra, ale jak to zrobić szybko i bezboleśnie …

O tym właśnie będzie ta seria postów. Zapraszam do lektury:

  1. Wstęp
  2. Co to jest dobra architektura ?
  3. Od czego zacząć projektowanie dobrej architektury ?
  4. Architektura wspierająca podejście Domain First
  5. Wnioski

Marcin Markowski

Zdjęcie Marcin Markowski
Trener

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.