Peterův princip říká, že v hierarchické organizaci jsou lidé povyšováni tak dlouho, až se dostanou na pozici, na kterou už nestačí. Je to logický důsledek snahy povyšovat lidi, kteří se na svém místě osvědčili – jednoho dne jsou povýšeni do funkce, kterou už nezvládnou, a tam se jejich postup zastaví.
Generalizace tohoto principu říká, že cokoli, co funguje, bude používáno pro stále složitější a odtažitější úkoly, až to bude nasazeno někde, kde to už fungovat nebude. Každý z nás jistě dokáže vyjmenovat několik takových příkladů z oboru software a IT vůbec. Nástroje, původně napsané pro určitou konkrétní oblast, se ukázaly životaschopnými – a za chvíli je vývojáři ohýbali pro použití v oblastech, kde víc práce zabralo samotné ohnutí oblíbeného nástroje než použití jiného, vhodnějšího.
Softwarový Peterův princip má význam lehce odlišný. Popisuje vývoj softwarového projektu, který se pomalu stává složitějším a složitějším, až sami vývojáři přestanou rozumět tomu, na čem vlastně pracují, a projekt ještě chvíli jede setrvačností, dokud s rámusem nepadne. Následně je označen štítkem EPIC FAIL
a starší kolegové jím straší ty služebně mladší.
Příčiny takového selhání mohou být tři (a většinou chodí ruku v ruce). První příčinou mohou být nezkušení vývojáři. Druhou příčinou pak vývojáři sice zkušení, ale nekompetentní. Definici „nekompetentního vývojáře“ nabízí Steve McConnell v knize Code Complete. Podle něho jsou nejlepší vývojáři ti, kteří pochopili, že je důležitější komunikovat s lidmi než se strojem. A nemusí to být jen třeba zákazníci nebo uživatelé – je potřeba komunikovat i s lidmi, co se o kód budou starat po vás. McConnell říká, že nekompetentní programátor upřednostňuje pokročilé a složité konstrukce či málo známé vlastnosti programovacích jazyků („programování na hraně“) před čitelností kódu. Kód psaný takovými programátory zvyšuje složitost celého projektu (i když mnozí z nich považují právě takové složité konstrukce za znak opravdového machra, co fakt do toho jazyka vidí).
Třetí příčinou selhání podle Peterova principu je ztráta koncepční jednoty. O tomto problému jsme si už na Zdrojáku říkali v článcích o projektovém řízení – ve chvíli, kdy začnou vývojáři podléhat nadšení z toho, co všechno by do projektu ještě mohli přidat, a nesoustředí se na základní funkčnost, je celý projekt na nejlepší cestě do pekel. Proto je potřeba, aby projekt řídil jeden člověk (nebo malý tým), který právě tyhle tendence udrží na uzdě a dokáže vývoj směřovat k určitému cíli. V projektech bez silného vedení a jasně dané koncepce se míchají otázky návrhu s otázkami implementace, a jejich řešení bývá ponecháno na uvážení programátorů. V případě, že mají programátoři v těchto oblastech přílišnou volnost, začnou přidávat nové funkce a zkoušet nové postupy a přepisovat už napsaný kód – a celý projekt se pak sype jak domek z karet.
Smradlavý kód
Vývojář s mnohaletou zkušeností dokáže kouknout na cizí kód a – aniž by ho podrobněji studoval – říct: S tím budou problémy. Jak to pozná? Většinou intuitivně. Špatný kód, se kterým budou problémy, totiž zapáchá (Code Smell). Co si pod takovým smrdutým kódem představit?
Nejčastější „smradlavé konstrukce“ jsou takové, o nichž každý programátor s alespoň základním teoretickým vzděláním ví, že je dělat nemá (ale v praxi pak vznikají „nějak samy“). Například duplikovaný kód – stejný nebo velmi podobný kód na různých místech. V OOP to jsou třeba příliš velké třídy, třídy s velkým množstvím funkcí, dlouhé metody, nebo naopak třídy příliš krátké, příliš „líné“ (lazy class, freeloader). Zapáchající kód představuje třeba třída, která přepisuje svého předka takovým způsobem, že ji lze za potomka považovat už jen stěží (viz Liskov substitution principle a související Circle-ellipse problem). Zapáchá i třída, jejíž správné fungování závisí na konkrétní implementaci jiné třídy (inappropriate intimacy) nebo taková, která zneužívá metody jiné třídy.
Zapáchající kód vznikne i přílišným lpěním na dogmatech – například použitím složitého návrhového vzoru tam, kde by stačilo jednoduché a přímočaré řešení. Problém mohou signalizovat i literály (konstantní řetězce či čísla) roztroušené po celém kódu, nebo používání složitých jmenných konvencí pro odlišení případů, které měly být odlišené samotnou architekturou.
Kód, v němž se takové příznaky vyskytují, zkrátka čpí na sto honů, a i když je možné, že bude teď a tady fungovat a bude svou funkci plnit, je velmi pravděpodobné, že s ním budou problémy při další údržbě, třeba při nutnosti přidat nebo pozměnit nějaké jeho funkce. V takovém případě je téměř jisté, že se něco rozbije.
Antipatterny – „návrhové horrory“
Na rozdíl od návrhových vzorů, které nabízejí modelová řešení pro konkrétní situace a je dobré se jimi řídit (resp. ve standardní situaci použít standardizovaný vzor), jsou antipatterny spíš návrhové horrory. Jsou to často používaná (či „často vznikající“) řešení, která jsou možná funkční, ale z principu špatná. Popisují nejčastější kategorie vývojářských „nočních můr“. Pojďme si některé z nich představit.
Obrácení abstrakce (Abstraction inversion)
Obrácená abstrakce popisuje situaci, kdy kód sice dělá něco, co uživatel požaduje, ale autor tyto funkce nezpřístupní ostatním. Výsledkem je, že programátor musí tutéž funkci, která už je uvnitř implementovaná, napsat znovu, místo toho, aby ji prostě využil – nemá totiž jak.
Hrouda bláta (Big ball of mud)
Už samotný název tohoto antipatternu říká, jak vypadá takový kód. Je to kód, v němž není rozpoznatelná struktura; slepenec tříd, metod, rozhraní, to všechno s nejasnými vazbami a souvislostmi. Čeština má pro takový kód rčení „prase aby se v tom vyznalo“.
Databáze jako komunikační rozhraní (Database-as-IPC)
Někdy není zbytí a prostředky, co máme k dispozici, jsou tak omezené (představme si např. sdílený LAMP hosting), že je potřeba řešit komunikaci mezi procesy pomocí databáze, v níž si nasimulujeme frontu zpráv. Což ale neznamená, že to je správné řešení. Správné řešení je použít vhodný IPC nástroj.
Pozlacení (Gold plating)
I tento antipattern jsme si už představovali v článcích o principu „good enough“. Každý projekt se dostane do bodu, za nímž už se nevyplatí vynakládat další prostředky na vývoj funkcí, protože jejich přínos je nižší než ty vynaložené prostředky. Takové perfekcionalistické „vyvíjení za hranicí rentability“ lze přirovnat k pozlacování kuchyňského nože – je to zbytečné, nepřináší to žádné zásadní vylepšení ani novou funkci a výsledek je jen dražší.
Efekt vnitřní platformy (Inner-platform effect)
Program někdy nabízí takové možnosti přizpůsobení, rozšíření, doplnění, upravení a nastavení, že se stává sám vývojářskou platformou. Jako příklad lze použít známý bonmot: „EMACS je skvělý operační systém, kterému chybí jen použitelný textový editor“.
Nafouknuté rozhraní (Interface bloat)
Navrhněte rozhraní tak mocné a schopné, že bude extrémně složité ho implementovat.
BaseBean
Tento antipattern popisuje situaci, kdy potřebnou funkci z pomocné třídy dědíme, místo toho, abychom ji na tuto třídu delegovali.
Kruhová závislost (Circular dependency)
Mějme třídu A, která je závislá na třídách B a C. Třída C je závislá na třídě D, která je závislá na třídách B a E, a třída E je závislá na třídě A. Nebo třídu P, která závisí na třídě Q, která závisí na třídě P. V extrémním případě pak „rekurze: viz rekurze“.
Božský objekt (God object)
Už jsme na něj narazili výš, v části o zapáchajícím kódu. Božský objekt vznikne sloučením velkého množství (leckdy nesouvisejících) funkcí do jednoho místa.
Objektové orgie (Object orgy)
Stav, kdy vývojář rezignuje na zapouzdření objektů a všichni tak mají neomezený přístup ke všem vnitřním hodnotám a metodám.
Poltergeist
Poltergeist je mysticky vznikající a zase mizící objekt s krátkou životností. Typicky vznikne, zavolá nějakou funkci, a zase zmizí. Často bývá plodem programátorova předjímání, že tam někde bude někdy v budoucnu něco složitějšího, a ono tam nakonec nic složitějšího není, ale zbytečný mezikrok tam straší dál.
Sequential coupling
Třída, která vyžaduje, aby její metody byly volány v přesně daném pořadí (a to nikoli z logiky věci, ale kvůli implementaci).
Problém joja (Yo-yo problem)
Tento problém je patrný v situaci, kdy se programátor snaží pochopit závislosti tříd a dívá se na jejich graf. Když mu pohled létá nahoru a dolů, jako kdyby sledoval jojo, je to příznak, že struktura trpí tímto antipatternem (nebo že dokumentaci tvořil sadista, co chce ostatním znepříjemnit pochopení problému). Často se vyskytuje při extrémním „rozdrobení“ struktury na malé kousky, které jsou pospojovány zcela zběsilým způsobem.
Akce na dálku (Action at a distance)
Nečekaná interakce mezi velmi vzdálenými částmi systému. Třeba systém, kde si TCP/IP stack volá pro výpočet čísla sekvence ovladač tiskárny.
Slepá víra (Blind faith)
Slepou vírou se proviní každý, kdo:
- spoléhá na to, že chybu opravil správně,
- spoléhá na to, že funkce vrátí správnou hodnotu,
aniž by si to otestoval. Bude potrestán prapodivnými chybami, které se náhodně projevují a nelze je vystopovat.
Kotva (Boat anchor)
Po delším vývoji najdete v systému části kódu, které už nikdo nepoužívá, ale přesto tam jsou. To jsou právě takové kotvy.
Kargokultické programování (Cargo cult programming)
Programátoři, vyznávající kargo kult, se projevují tím, že mechanicky používají vzory a postupy, aniž by opravdu chápali, proč je používají. A týká se to nejen programátorů…
Skrývání chyb (Error hiding)
Někteří vývojáři vyznávají princip „chyba je selhání vývojáře“. Někdy takový princip vyznává vedoucí týmu. Logickým protihmatem je tedy všechny výjimky odchytit, nevypsat nic a tvářit se, že chyby nejsou. A po pravdě řečeno – vypsat chybové hlášení „Došlo k chybě, ouha“ je v zásadě totéž jako nevypsat nic.
Loop-switch sequence
Představte si, že máte v kódu vykonat určitou posloupnost činností. Pokud chcete využít tento antipattern, udělejte si smyčku FOR s proměnnou, řekněme, i, do těla smyčky dejte switch podle této proměnné a pro každou hodnotu nadefinujte jednu činnost. Úspěch zaručen!
Magická čísla (Magic numbers)
a = n ^ 0.15915494309189533576888376337251
– prosím? Nechť zvedne ruku každý, kdo na první pohled pochopil, že to číslo je 1/(2*PI)
… Pokud už nějaké takové číslo potřebujete, vložte ho jako pojmenovanou konstantu a vysvětlete význam.
Copy and paste programming
Programování metodou copy-paste porušuje hned několik zásad správného programování. Zamyslete se, jestli by nešlo nahradit zkopírovaný (a pozměněný) kód nějakým obecným řešením.
Zlaté kladivo (Golden hammer) a stříbrná kulka (Silver Bullet)
Oblíbený postup, u něhož věříme, že je vždy použitelný, je takové zlaté kladivo. Oblíbený postup, u kterého věříme, že vyřeší všechny možné problémy, je stříbrná kulka. Obojí je většinou iluze.
Faktor nepravděpodobnosti (Improbability factor)
V systému je známá, i když vzácná chyba, ale místo toho, abychom s ní počítali a ošetřili ji v kódu, tak se spoléháme na to, že zrovna u nás nenastane. Proč si přidělávat práci, že?
Programování metodou pokus-omyl (Programming by permutation, „programming by accident“)
Cyklus změna – test – změna – test…, aniž bychom věděli, co máme změnit a proč, ale spíš naslepo střílíme a čekáme, že to jednou začne fungovat.
Vynalézání kola (Reinventing the wheel)
Existuje přijatelné a odpovídající obecné řešení problému, ale my si přesto zvolíme cestu psaní vlastního kódu s bonusovou možností nasekat stejné chyby, jaké udělali tvůrci toho řešení, a přidat i pár nových.
Vynalézání hranatého kola (Reinventing the square wheel)
Existuje přijatelné a odpovídající obecné řešení problému, ale my si přesto zvolíme řešení na míru, které bude mnohem horší.
Projektové antipatterny
Pochod smrti (Death march)
Všichni vědí, že projekt skončí katastroficky, ale skrývají skutečný stav věcí, aby se vyhnuli zastavení a zrušení celého projektu. Někdy se to podaří utajovat a celý projekt uměle udržovat při životě až do chvíle, kdy přijde Den D. Jiná definice pochodu smrti říká, že jde o situaci, kdy jsou vývojáři nuceni pracovat přesčas a o víkendech, i když je každému jasné, že termín dokončení je naprosto nesmyslný a nelze to stihnout, ani kdyby měl den 36 hodin.
Groupthink
Termín z psychologie, popisuje situaci, kdy se skupina lidí uzavře před pohledem zvenčí a navzájem se ujišťují, že jejich pohled na věc či zvolený postup je správný. Též „nemoc výborů“ a „problém komisí“.
Analysis paralysis
Tak dlouho se vypracovávají analýzy, zprávy, rozbory a posudky, až už není potřeba nic programovat. Důsledným analyzováním všeho a neustálým svoláváním porad lze zaměstnat hned několik týmů na dlouhé měsíce, během nichž budou všichni pracovat, aniž by vytvořili cokoli funkčního.
Navrženo komisí (Design by committee)
Návrh potřebuje jednotnou vizi. V situaci, kdy do návrhu mluví každý a každý považuje svůj pohled za stejně důležitý jako pohled ostatních, vznikne nekoncepční zmetek.
Komise rozhodla (Escalation of commitment)
…a pak se ukáže, že její rozhodnutí je špatné. Ovšem nikdo ho už není schopen odvolat, a tak se dál pokračuje špatným směrem.
Morální hazard (Moral hazard)
Popis tohoto antipatternu je všeříkající: o věcech rozhoduje člověk, který nikdy nepocítí následky svého rozhodnutí.
Houbový management (Mushroom management)
Zaměstnanci jsou v prostředí připomínajícím pěstírnu hub: udržováni v temnotě, obklopeni hnojem, a jakmile vystrčí hlavu, tak jsou odříznuti a odstraněni. Tato obrazná definice popisuje situaci, kdy management cosi rozhoduje, ale zaměstnanci nedostávají pořádné instrukce, pokyny si často protiřečí, všechno je tajné, nikdo do ničeho pořádně nemůže mluvit, nikdo neví, kdo o věcech vlastně rozhoduje…
A mnohé další…
Antipatternů je mnohem víc, vybrali jsme jen některé z nich. Zájemci najdou víc v literatuře. Nezbývá než popřát všem takovou práci, kde nebudou muset žádný z nich používat.
Tento text čerpá z popisů antipatternů na Wikipedii, a vychází proto pod licencí CC-BY-SA.
Přehled komentářů