Softwarová komplexita
Bronislav Klučka, 06. 6. 2025 22:47
Komplexita je úhlavní nepřítel softwarového designu a architektury. Primárním úkolem softwarového architekta je odstranit, redukovat a spravovat komplexitu – v tomto pořadí. Ale co když samotná podstata problému, který řešíte, je komplexní? Co potom? Co vlastně znamená řídit komplexitu a co je vůbec komplexita?
Co je komplexita?
Existuje mnoho definic komplexity, přičemž žádná není 'jediná správná'. Záleží na kontextu (například na užití v různých vědeckých disciplínách). Pro potřeby tohoto článku však definuji komplexitu takto:
Nelineární kauzalita: není možné předpovědět budoucnost.
Interakce mezi částmi systému mění chování samotných částí nepředvídatelným způsobem.
Interakce mezi libovolnými částmi systému může začít nebo skončit v libovolnou chvíli.
Než vůbec prozkoumáme komplexní prostor, podívejme se na nekomplexní systém: spalovací motor. Spalovací motor je komplikovaný kus technologie, nicméně není komplexní; přesně následuje fyzikální a chemické zákony. Ano, lidé mohou udělat chybu, motor se může rozbít, nebo může dojít k únavě materiálu a motor se rozbije. Nicméně i toto je ve finále řízeno přírodními zákony, a chování je tudíž předvídatelné bez ohledu na míru komplikovanosti nebo na to, jestli si někdo všiml nějakého problému. Interakce mezi částmi motoru mění tyto části, ale opět předvídatelným způsobem.
Podívejme se teď na komerční vývoj softwaru:
Víte, jestli budou mít rádi váš software? Víte, jaké změny budete provádět na základě zpětné vazby? Můžete to plánovat? Můžete nyní navrhnout architekturu, která bude co nejlépe odpovídat potřebám za rok? Víte, jak se změní požadavky na software? Víte, jak zareaguje konkurence?
Ve skutečnosti existují čtyři typy komplexity v softwaru samotném (bez ohledu například na business apod.).
esenciální komplexita
komplexita škálování
komplexita podpůrných částí
náhodná komplexita
Esenciální komplexita
Esenciální komplexitou rozumíme samotnou komplexitu problému, který řešíte. Z podstaty věci je software, který sčítá dvě čísla, jednodušší než software jako Excel. To nemá nic společného s řešením; esenciální komplexita vyplývá ze zadání.
Jedním z problémů, se kterými se setkávám, je předpoklad řešení, který se týká esenciální komplexity. „Když děláme tohle, musíme to udělat takto.“ Přeskočí se komplexita a jde se rovnou na řešení (kód). Nejprve bychom měli porozumět komplexitě zadání, než se pustíme do programování.
Míru esenciální komplexity nelze změnit bez změny zadání – to ji dělá esenciální. Komplexní systém se nedá zmenšit nebo rozdělit za účelem zjednodušení (komplikovaný ano). Existuje však možnost přesunout komplexitu jinam.
Jinými slovy: co dělá esenciální komplexitu problematickou a jak s ní pracovat? Jelikož je esenciální a musí existovat pro vyřešení problému, je možné pouze řídit dva parametry.
Problémem se myslí problém, příležitost, zadání, úkol... prostě to, co má programátor vyřešit.
Naše chápání problému
Tady může pomoci praktika jako Event Storming, ale tohle není o praktikách, tohle je o chápání domény. Je nezbytné, aby developeři měli možnost hovořit s doménovými experty, stakeholdery a uživateli přímo, bez zprostředkování.
Může existovat prostor pro čistého produktového manažera (i když je obvykle zbytečný), nicméně PM (PO) nemůže být gatekeeper informací, ani ten, kdo rozhoduje, co a jak bude uděláno.
Může existovat prostor pro čistého programátora (i když je obvykle zbytečný), nicméně schopnost psát kód je ta nejméně důležitá vlastnost u softwarového inženýra.
K čemu je pochopení problému? Proč je to důležité? Úkolem developera je řešit problémy, obvykle pomocí kódu. Aby to bylo efektivní i efektní, developer musí problém pochopit, aby dokázal navrhnout řešení. Developer je tím (nebo by měl být tím), kdo rozumí tomu, zda řešení bude jednoduché, nebo složité, jestli existuje více řešení daného problému atd. A toto je možné rozhodnout pouze na základě diskuze. Kód je jen implementace výstupů této diskuze.
Rozsah problému
Ale podívejme se na to i trochu technicky. Negativním dopadem je zde rozsah kódu. Pokud máte monolit o 100 000 řádcích, není možné o všem vědět, znát všechny dopady změn a jejich rozsah.
Co potřebujeme? Systém s velmi dobře definovanými sub-systémy a minimem zodpovědností, které komunikují jasně definovaným API. Cílem je zde schopnost provádět změny:
pokud se změna sub-systému neprojeví v API, nemusíte si dělat starosti o nic jiného
pokud se změna dotkne i API, dopad je definován konzumenty daného API
Řešeními tu je:
high cohesion, low coupling
modularization
separation of concerns
a vlastně každý princip a pattern, který je s nimi spojen.
V dalším článku probereme zbylé tři typy komplexity.