
Softwarová komplexita

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 vůbec znamená managovat komplexitu a co je vůbec komplexita?
Co je komplexita?
Existuje mnoho definic komplexity, žádná "jediná správná". Záleží na kontextu (např. na užití v různých vědeckých disciplínách). Pro potřeby tohoto článku, nicméně, definuji komplexitu takto:
- Nelineární kauzalita: nelze 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/skončit v libovolnou chvíli.
A před tím, 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 a motor se rozbije, 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 toho, jestli si někdo všiml nějakého problému, nebo ne. 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 software:
Víte, jestli budou mít rádi váš software? Víte, jaké změny budete dělat na základě zpětné vazby? Můžete to plánovat? Můžete teď 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í 4 typy komplexity v softwaru samotném (bez ohledu např. na business apod.)
- esenciální komplexita
- komplexita škálování
- komplexita podpůrných částí
- náhodná komplexita
Esenciální komplexita
Esenciální komplexitou se rozumí samotná komplexita problému, který řešíte. Z podstaty věci, software, který sčítá 2 čísla je jednodušší, než software jako Excel. Toto nemá nic společného s řešením, esenciální komplexita vyplývá ze zadání.
Jedním z problému, se kterým se setkávám, který se týká esenciální komplexity je předpoklad řešení. "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 vrhneme na programování.
Míra esenciální komplexity se nedá změnit bez změny zadání - to ji dělá esenciální. Komplexní systém se nedá zmenšit, rozdělit, za účelem zjednodušení (komplikovaný ano). Ale existuje 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 managovat 2 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 Stroming, ale toto není o praktikách, toto 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 napřímo, bez interpretace.
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í, nebo 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á u softwarového inženýra.
K čemu pochopení problému je? Proč je to důležité? Úkolem developera je řešit problému, obvykle pomocí kódu. Aby toto bylo efektivní i efektní, developer musí problém pochopit, aby dokázal navrhnout řešení. Developer je tím (měl by 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 jenom implementace výstupů této diskuze.
Rozsah problému
Ale podívejme se na to i trochu technicky. Negativním dopadem je tu 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 s minimem zodpovědností, které komunikují jasně definovaným API. Cílem je tu schopnost dělat 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.