
Architektura
Bronislav Klučka, 22. 7. 2025 15:21
"Softwarová architektura je návrh API, databáze a měla by být robustní a stabilní."
Na předchozí větě není skoro nic pravda. Moderní softwarová architektura je něco velmi jiného.
2 věci se právě dějí u mého aktuálního zákazníka, které mě přiměly napsat tento článek. Probíhá nábor developerů a často, když mluví o posledním zaměstnání, se setkávám s prohlášením "a dělal jsem i architekturu". Když začnu vyzvídat, tak to je návrh API a databáze. Při vší úctě, to není architektura, to jsou příliš taktická rozhodnutí. A tým u zákazníka aktuálně píše novou verzi API a soustředí se na způsob implementace DDD, na adresářovou strukturu a jak to udělat "správně a stabilně". Ani to není architektura, příliš taktické... Ve všech zmiňovaných případech chybí to hlavní. To, co je vlastně cílem architektury. To, co pohání víše zmíněná rozhodnutí.
Co je softwarová architektura
Tak tady to máte:
Cílem softwarové architektury je zajistit, aby bylo možné software a jeho příslušenství udržovat a dlouhodobě evolučně rozvíjet v rámci hranic stanovených stakeholdery ve prospěch zákazníka. Náročnost údržby a rozvoje by měla odpovídat náročnosti zadání a neměla by být výrazně ovlivněna existujícím kódem. Strategií, jak toho dosáhnout, je management komplexity.
Ok, podívejme se na jednotlivé části:
- příslušenství
Vlastně "všechno kolem SW"... kód, infrastruktura, CI/CD, testy... vše, co je potřeba k doručení hodnoty zákazníkovi.
- udržování
Hotfixy / bugy / drobné úpravy.
- dlouhodobý evoluční rozvoj
-
Pokud se nejedná o menší zakázkový vývoj, většina software, který píšeme, bude v provozu roky, 5 let, 7 let, 10 let... Musíme být schopni přidávat do SW větší, nové moduly.
Pokud píšeme např. účetní software, musíme být schopní přidat modul, který generuje daňová přiznání a ostatní podobné dokumenty (evoluce z hlediska rozšíření). Nikdo ale nemůže čekat, že SW jednoduše upravíme, aby řídil atomovou ponorku (to není moc evoluční vzhledem k předchozí funkcionalitě).
- hranice stanovené pro vývoj
-
Rozpočet, očekávaný počet uživatelů, nároky na reporting, zákonné povinnosti, apod.
- náročnost
-
Logicky, drobnější rozvoj by měl být jednodušší a rychlejší, než přidání nového velkého modulu. A tak by to mělo být po celou životnost produktu.
Kód by neměl obsahovat částí, kterým developeři moc nerozumí, do kterých se bojí sáhnou, aby se něco nerozbilo, které blokují další rozvoj. Rychlost vývoje by měla být +- konstantní po celou životnost produktu a pokud se bude měnit, měla by být rychlejší a rychlejší právě díky kódu, který už existuje.
- strategie
-
Správa komplexity ke alfou a omegou všech dalších postupů, které volíme. Komplexita kódu musí odpovídat tomu, co kód řeší. Jednoduchý modul by měl vypadat jinak, než složitý. Není jediný důvod "být konzistentní", to pouze povede k tomu, že malé moduly budou zbytečně komplikované a složité moduly nebudou navržené dostatečně odpovídajícím způsobem.
- ve prospěch zákazníka
-
Vše, co děláme, děláme kvůli pozitivnímu dopadu pro zákazníka hned po nasazení. Nepíšeme/neupravujeme kód jen tak pro nic za nic, nepíše kód, "protože jedno dne se nám to může hodit". Hodnota pro zákazníka je nejvyšší hodnota.
Form over substance
Pro ty, co nemluví anglicky, nadpis znamená "forma nad podstatou". Je to něco, co vidím často, snaha o "dokonalý kód", "perfektně rozdělený". Mnohem více času stráveného nad strukturou, než obsahem. Prostě napište kód, který dělá, co potřebujete a pak ho refaktorujte, aby se v něm dalo vyznat. Pokud do něj musíte sáhnout, refaktorujte ho, abyste se připravili, dopište funkcionalitu a ukliďte ho... a příště opakujte.
Další věc, kterou vidím často je tvorba struktury kódu před tím, než vůbec píšu funkcionalitu. Struktura pak často neodpovídá potřebě funkcionality. Příliš složitá, nebo příliš jednoduchá.
Soustřeďte se na to, aby kód dělal, co má dělat a aby byl čitelný a upravitelný.
A k čemu jsou teda všechny ty patterny?
K řešení specifických problémů. Už jsem to někde psal, ale čím specifičtější pattern, tím specifičtější problém řeší. Jedná se o taktická rozhodnutí na jednom místě kódu, nebo v jedné funkcionalitě. Není nic špatného na implementaci patternů, naopak! Ale řešte s nimi praktické problémy, které máte. Neřešte problémy, které nemáte, neimplementujte je proto, že "ono se to tak dělá".
Seshora dolů
Ok, cíl a hlavní strategii máme... co potom?
- high level separation of concerns
- high cohesion and low coupling
- modularization
Začněte tady, tyto 3 principy slouží ke snížení komplexity a zvýšení čitelnosti a udržitelnosti. Jděte níže, k taktice, až když musíte.
- Je jasné, co které části kódu mají dělat?
- Je to, co spolu souvisí spolu a to co spolu nesouvisí od sebe?
- Je zřejmé, kde končí hranice jedné funkcionality a začínají hranice další?
Pokud ano, nekomplikujte něco, co může být jednoduché. Overengineering vidím častěji, než underengeneering. A věřte tomu, refaktorovat underengeneered kód je jednodušší, než naopak.