Totalna frustracja w Garmisch-Partenkirchen roku 1968 zrodziła pojęcie kryzysu oprogramowania. Zamiast sprytnych pętli, NATO zobaczyło wtedy rozjechane budżety i systemy radarowe, które przy byle teście padały martwe. Mądrzy ludzie pojęli natychmiast, że bez mapy pięćdziesięciu koderów stworzy jedynie tysiące bomb z opóźnionym zapłonem. Inżynierię oprogramowania powołali do życia, bo liczby przestały się zgadać, a Zbyszek – jedyny posiadacz dokumentacji w swojej głowie – akurat wyjechał na zasłużony urlop. Nie o kody źródłowe wtedy chodziło, lecz o niemożność przewidzenia, kiedy ten cały cyrk w ogóle zacznie działać. Projektowanie systemów wojskowych przypominało wówczas wróżenie z fusów, a nie rzetelną pracę naukową. Wierzono naiwnie, że wystarczy dokupić więcej pamięci operacyjnej, by błędy logiczne same wyparowały z asemblera.
Architektura to proste równanie Perry’ego i Wolfa:
$$Architektura = {Elementy, Formy, Uzasadnienie}$$
. To ostatnie, zwane Rationale, odróżnia inżyniera od przedszkolaka, który bezmyślnie klika w Miro i Dockerem się bawi bez sensu. Wybierasz Kafkę dla pięciu użytkowników, bo tak na konferencji gadali? Perry i Wolf w grobach się przewracają, widząc twój projekt, który muli przez nadmiar niepotrzebnych warstw. Logika każdej decyzji waży u nas znacznie więcej niż najładniejszy diagram, więc albo masz twardy powód, albo tylko drogi prąd marnujesz. Elementy to te wszystkie klocki: bazy danych, serwisy, kolejki. Formy określają, jak te graty ze sobą gadają. Tu pojawia się wątpliwość – czy wiesz w ogóle, dlaczego używasz PostgreSQL zamiast MongoDB? Jeśli twoją jedyną odpowiedzią jest „bo wszyscy tak robią”, to architekturę właśnie zamieniłeś w kosztowną dekorację. Nie w każdym przypadku musisz budować bunkier atomowy, ale wiedzieć powinieneś, dlaczego stawiasz akurat płot z siatki.
Pięć par okularów serwuje model 4+1 Kruchtena, byś nie dostał zeza przy patrzeniu na jeden widok. Użytkownik widzi tylko spinner, ty zaś ogarniasz wątki, encje i fizyczne serwery we Frankfurcie. Często juniorzy warstwy mieszają, wmawiając wszystkim, że nowe pole w tabeli to już wielka funkcja biznesowa. To zalezy od perspektywy, ale reguły walidacji nie naprawisz nigdy, grzebiąc jedynie w parametrach maszyny. Rozdzielenie tych światów to twój najświętszy obowiązek, a nie luźna sugestia. Perspektywa logiczna opisuje, co system robi, a fizyczna – gdzie to właściwie leży i czy spłonie, gdy administrator wyleje kawę na racka.
Dygresja krótka: widziałem kiedyś diagram, który miał siedemnaście kolorów, ale nikt nie potrafił wskazać, którędy płynie prąd przy autoryzacji. Scenariusze (ten magiczny „+1”) to poligon doświadczalny. Jeśli twój plan nie wyjaśnia, co się stanie, gdy baza danych złapie czkawkę na 300 milisekund, to te diagramy możesz sobie oprawić w ramkę i powiesić w toalecie. Kod jako fizyczne pliki w repozytorium to kolejna soczewka, o której zapominasz, tworząc strukturę katalogów przypominającą wysypisko śmieci po przejściu trąby powietrznej. Piękna logika w głowie nic nie znaczy, jeśli programista musi szukać definicji klasy przez godzinę w trzech różnych modułach.
Decyzje architektoniczne (ADR) z Confluence do repozytorium kodu przenieś, zanim w muzeum technicznych plotek się zamienią. Leniuchy brak planu pod hasłem „zwinność” chowają, a to zwykły sabotaż logiki i twojej własnej przyszłości. Prawdziwa elastycznosc rusztowania wymaga, a nie pisania na kolanie, bo osiemdziesiąt procent długu w startupach generują asy bez planu B i C. Jeśli ADR-a o strategii cache’owania szukasz w folderach dłużej niż dziesięć sekund, to zwyczajnie czas na srogi rachunek sumienia. Dokumentacja w Markdownie obok kodu leżeć musi, wersjonowana tak samo jak twoje marne funkcje. Unikasz dzięki temu sytuacji, w której nowa osoba w zespole próbuje zaimplementować coś, co wywaliliście trzy miesiące temu po sześciogodzinnej kłótni na Slacku. Przejrzystość to nie luksus, to przetrwanie.
Weźmy na warsztat Wilda Software, gdzie pracowałem dekadę temu. Zachciało nam się mikroserwisów, bo artykuł w internecie obiecał nam złote góry i wieczną skalowalność. Skończyliśmy z systemem, gdzie jeden błąd w module płatności kładł na łopatki cały interfejs użytkownika, bo zapomnieliśmy o asynchroniczności. Architektura na papierze wyglądała jak arcydzieło, ale w praktyce była to sieć ciasno powiązanych sznurków. Dopiero wdrożenie RabbitMQ i rozbicie tych zależności pozwoliło nam odetchnąć. To nie była innowacja – to było łatanie dziur powstałych z braku myślenia o awariach. 300 ms opóźnienia potrafi zabić konwersję w e-commerce szybciej niż brak promocji. Tutaj pojawia się doprecyzowanie: nie każdy błąd to wina kodu, czasem to wina złych założeń na etapie rysowania prostokątów.
W głowie się nie mieści, jak bardzo programiści nienawidzą pisać o swoich wyborach. Wolą spędzić noc na debugowaniu niż piętnaście minut na opisie, dlaczego wybrali bibliotekę X zamiast Y. “Kod sam się dokumentuje” to kłamstwo, które powtarzają sobie ludzie bojący się konfrontacji z własną logiką. Jeśli nie umiesz zapisać argumentów za swoim rozwiązaniem, to prawdopodobnie sam go nie rozumiesz. Sytuacja ta prowadzi do powstawania tzw. legacy, czyli kodu, którego wszyscy się boją dotknąć, bo nikt nie wie, co autor miał na myśli przed trzecią kawą. Proporcja czasu spędzonego na myśleniu do czasu klepania w klawiaturę powinna wynosić co najmniej 2:1. W przeciwnym razie produkujesz tylko techniczny hałas.
Zwinność (Agile) to nie jest darmowa przepustka do robienia bałaganu. To metoda reagowania na zmiany, która bez solidnej bazy kończy się katastrofą przy pierwszej próbie dodania nowego modułu. Elastyczny musisz być w podejściu do klienta, a nie do zasad grawitacji w systemie. Brak planu to nie elastyczność, to zwykłe lenistwo intelektualne maskowane modnymi frazesami. Gdy system zaczyna puchnąć, te wszystkie “szybkie poprawki” wracają jako kosztowne refaktoryzacje trwające całymi kwartałami. Nie w każdym przypadku trzeba projektować od razu system na miliony requestów, ale zawsze trzeba wiedzieć, gdzie kończy się twoja wiedza, a zaczyna zgadywanie.
Dbałość o strukturę danych to podstawa, o której juniorzy zapominają w pogoni za nowym frameworkiem w wersji beta. Baza danych to nie jest worek na ziemniaki, do którego wrzucasz wszystko jak leci w formacie JSON, bo “schematy są nudne”. Poprawna normalizacja (albo świadoma denormalizacja) to fundament, na którym stoisz. Bez niego twoje API będzie wolniejsze niż wysyłanie listów gołębiami pocztowymi. Zastanów się dwa razy, zanim dodasz kolejną tabelę łączącą wszystko ze wszystkim. Czystość architektury to nie estetyka, to mniejsze rachunki za chmurę i mniej siwych włosów na twojej głowie.
Autor: programista z 15 letnim doswiadczeniem, expert, redaktor z zacieciem do pisania lekkich i zartobliwych tekstow