Zobrazují se příspěvky se štítkemprojekt. Zobrazit všechny příspěvky
Zobrazují se příspěvky se štítkemprojekt. Zobrazit všechny příspěvky

pátek 27. července 2018

Paralýza bez analýzy


Kašleme na ně, radši vyhyneme!

Je známým faktem, že tzv. „antipatterny“ si lidé pamatují snáze než „patterny“, čili vzory. Týká se to i pojmu Analysis-Paralysis (analýza-paralýza), nebo naopak „Extinct by Instinct“ (vyhynutí instinktem). Přitom spousta vývojářů už někdy slyšela o dokumentech, kterým se říká „detailní návrh systému“, „specifikace požadavků“, UML diagramy, „use case“, „popisu chování“, … atd.

Typický vývojář se hrozně těší, až si do svého výtvoru prvně klikne myší, pošle mu zprávu a v ideálním případě dokonce dostane odpověď, až to zkrátka konečně začne něco dělat. A tak se vykašle na analýzy a dokumentaci, a začne bastlit, během čehož si teprve začne uvědomovat, co všechno ještě bude muset přidat, předělat, průběžně upravit svoje původní nápady, ale zároveň nerad maže to, co už udělal.
A když už to má všechno za sebou, nenávidí opravování chyb, a za nic na světě nezačne psát automatické testy – čím jsou náročnější, tím větší je odpor. A náročnější jsou tím víc, čím složitější je implementace i rozhraní, i čím složitější je popis chování aplikace.

No počkat, „popis chování aplikace“? Ten ale neexistuje, jeho jediná instance je ve vývojářově hlavě, a permanentně se mění, nakonec dojde ke vzpouře mysli, která ve výsledku začne prosazovat chyby jako chtěné vlastnosti. Vývojář se hrubou silou pokusí protlačit svůj mizerný geniální výtvor přes jakákoliv akceptační pravidla týmu, šéfů, zákazníka, kohokoliv, jen aby to měl za sebou.

Kolikrát se tohle zopakuje, než vývojář „vyhoří“?
Kolikrát se tohle zopakuje, než s ním tým ztratí trpělivost?
Kolikrát se tohle zopakuje, v kolika týmech, u kolika zaměstnavatelů, u kolika zákazníků?

Mockrát.
Zákazník si zvykne a bojí se, že po utracených milionech to jinde bude zase stejné.
Zaměstnavatel má problém sehnat jakéhokoliv vývojáře, snaží se udržet si i ty špatné.
Nejmocnější je podle mého soudu tým samotný, dobrý tým se musí nutně zbavovat členů, kteří mu kazí pověst i dílo, bez ohledu na to, že takovými změnami přidělává práci personalistům firmy i svým šéfům. Samozřejmě to je až krajní stav, kdy dotyčného nelze proškolit, kdy se nedokáže sžít s fungováním kvalitního týmu. Naopak pokud není kvalitní tým jako celek a nelze z něj přiměřeným úsilím kvalitní tým učinit, není důvod v něm setrvávat.

Žádné násilí ale není nutné.

Někteří vývojáři dokonce tvrdí, že je vysoká škola nic nenaučila. Zapomínají, co všechno se jim dostalo do podvědomí, přestože si nepamatují podrobnosti. Přehlížejí, že je škola naučila se nejen učit, ale i zapomínat nepotřebné detaily, vybírat jen to podstatné a detaily vyhledávat a chápat. Schválně, víte nebo aspoň tušíte, o čem je řeč? Jak často si na to vzpomenete při vývoji?

  • O(n)
  • B-tree
  • SHL, SHR
  • BCNF
  • Transformační matice
  • Konečný automat
  • Spolehlivost systému
  • Korelace jevů
  • Riemannův integrál
  • Svobodovy mapy
  • Násobení matic
  • Rekurze
  • Podmínka nutná, nikoliv postačující.
Vývojáři rádi vyvíjejí, vynalézají, ale často neradi zapisují myšlenky a ověřují je, hledají souvislosti. K tomu musí časem dospět, obvykle s trochou donucení kvalitním týmem. Ano, kvalitní tým píše dokumentaci a píše analýzy – ne však protože je někdo vyžaduje, ale protože jsou užitečné!

Jak překonat odpor


Jak? Sněním. Už máte něco za sebou, tak si vzpomeňte, jak jste se v tom programování ztráceli minule. A co všechno jste už mohli vědět předem, kdybyste si dali tu práci. Ne, nepotřebujete začínat UML diagramy a těmi obrázky, které vám vnutili ve škole. Začněte smluvním popisem, který proberete se zadavatelem – nemusíte hned psát knihu, stačí sepsat si na papír co víte, a co byste chtěli vědět:
  • co aplikace má dělat
  • co aplikace nemá dělat (hodí se vytyčit „hranice“, odkázat se na související funkcionality)
  • jakým způsobem bude interagovat s klientem (browser, ws, db, ...)
  • kdo je klientem (server, člověk, jiná aplikace, …)
  • kolik je klientů (jeden? tisíc? lze počet regulovat? jak?)
  • jaký bude mechanismus kontroly oprávnění, co vše bude zohledňovat?
  • pokud jde o uživatelské rozhraní, jak bude vypadat, jak se bude chovat (co bude na formuláři, co se stane, když uživatel klikne sem nebo tam, má mu textové pole napovídat a jak?)
Pak pokračujte o něco blíž programování ...
  • jaký bude vliv na zátěž HW, nároky na disk, paměť, sítě?
  • alternativy technologií i přístupů
  • rizika – kde se dá očekávat problém? Dá se předejít prototypováním, matematickým modelováním, sběrem a statistickou analýzou dat?
Po pravdě taky se mi nechce psát analýzy, ale chuť se dá vylepšit právě prototypováním (něco naprogramujete, ale pak to vyhodíte, jen si zkusíte nějakou cestu) a i samotným faktem, že z napsané analýzy se všemi těmi nápady kolem má její autor mnohem lepší pocit, už protože ho navštívila řada dalších nápadů a inspirací, co s čím souvisí a jak by to asi mohlo být dobře.

Pravda, tu chuť obvykle trochu pokazí zákazník nebo kolegové-oponenti, ale po pár iteracích mají nakonec lepší pocit všichni a těší se, až to uvidí „žít“.

Dvakrát měř, jednou řež


Pozitivní je též to, že už se obvykle nezmýlíte v odhadu pracnosti řádově, byť tento odhad obvykle všechny šokuje, nakonec se ho dokonce možná i podaří dodržet, což je známka profesionality – samozřejmě se objeví také nápady, co seškrtat nebo odložit.

Při vývoji software není tolik důležitý materiál, o to důležitější je ale čas, který se velmi špatně odhaduje. Pro vysoké odhady obvykle nemá zákazník pochopení, na druhou stranu se rozhodně nevyplatí mu lhát a dávat mu jakkoliv optimistický odhad. Mnohem lepší je dát odhad spíše pesimistický a později třeba i zákazníkovi nabídnout slevu (což se ovšem málokdy stává, dělá to ale výborný dojem). 

Ošizením analýzy nebo interních testů a kontrol se také nic získat nedá, naopak dodáním „milestone“ verze k otestování zákazníkem nebo dokonce zatažením zákazníka do testování aplikace se dá vyhnout spoustě nedorozumění i problémů při akceptaci.
Tím spíš je pro obě strany dobré mít vše „na papíře“ - nikdy by pak neměl nastat stav, kdy zákazník dluží dodavateli několik milionů za vývoj aplikace, které odmítá zaplatit s tím, že půl roku o dodavateli neslyšel a nakonec se dodavatel pokusil předat něco, co není zákazníkovi k ničemu.

Interní (hlavně automatické) testy a kontroly však rozhodně neslouží k náhradě zákazníka, nýbrž k pokrytí celé řady cílů. Zákazník téměř nikdy netestuje aplikaci kompletně, ale spíše ověřuje, jestli plní jeho očekávání. Při tomto ověřování může dojít i ke změně požadavků zákazníka a prodražení aplikace – následovat musí dohoda, jak bude změna financována a jak je velká oproti stávajícímu zadání.

Automatické testy naopak pokrývají na různých úrovních:
  • zafixování již implementovaného chování
  • otestování funkcionalit, které testera napadly, nicméně není žádná záruka, že na ně narazí při ověřování zákazník (!)
  • otestování hraničních případů
  • otestování různých uživatelských scénářů
Z toho celkem jasně vyplývá, že část pokrytí kódu testy je nutně duplicitní – a přitom je velmi obtížné dosáhnout pokrytí 100%. Ten háček je ovšem v tom, že klíčové není pokrytí kódu testy, nýbrž pokrytí všech možných (tj. i velmi nepravděpodobných) scénářů včetně chybových. Vypočtené pokrytí kódu testy je jen pomůcka, protože žádný software nikdy nedokáže posoudit, jaký rejstřík kombinací stavů a událostí vůbec může nastat, natož které jsou vlastně důležité. 

Ve výsledku tudíž není až tak důležité procento pokrytí, mnohem důležitější je procento nepokrytého kódu, tj. kódu, přes který žádný automatický test ze všech sad vůbec neprošel. Není zrovna tam chyba? Dělá to to, co chcete?
Samozřejmě ani naopak pokrytí kódu testy neříká, že pokrytý kód je správně – pouze to, že nějaký test tudy prošel. Znovu tudy opakuji, pokrytí kódu testy jsou jen pomůcka; podmínka nutná, nikoliv postačující.

Proč jsem sklouzl k testům?


Protože první testy nelze psát na základě ničeho jiného než je nějaká forma analýzy, obzvlášť u přístupu „test driven development“, alespoň pokud chcete minimalizovat psaní zbytečného kódu i testů, které později zahodíte nebo v horším případě neužitečně ponecháte v aplikaci, čímž pro změnu prodražíte budoucí údržbu.

Prostě to udělejte dobře – a ne, tohle vážně není Vodopádový model vývoje, vše se dělá iterativně. Už na začátku je ale dobré mít alespoň hrubou představu, co že to vlastně vyvíjíte, a během chvíle doženete „rychlíky“, kteří se řídí instinktem, díky kterému se ale brzy začnou točit v kruhu. 
 
Myslíte, že ne?

P.S.: Příště už radši něco praktického ... ;)

pátek 21. července 2017

Manday není jednotka!

Tento příspěvek bude česky, protože se týká hlavně českých firem, tvořících software, a je podložen praxí, bohužel.

Pro některé je titulek možná šokující odhalení a děsný podraz, jelikož celý život krom jednotek Kč, EURO, hodina, den, týden a procento používali též "člověkoden" (manday) a "člověkohodinu" (manhour). O té poslední se zmiňovat ani nebudu, platí pro ní totéž, co pro tu v titulku.

Manday přece funguje

Ano, někdy funguje. Třeba při výkopových pracích bývá rozdíl mezi dělníky řádový jen výjimečně. Manažer si odhad pro jistotu vynásobí nějakým koeficientem a má skoro jistotu, že se termín stihne. Může dokonce jen s malou chybou počítat "cenu manday", atd.
Jenže my se bavíme o tvorbě software, kde jsou rozdíly mezi programátory, analytiky, testery i konzultanty obrovské.

Pepa není Franta

Máte velký projekt, který tvoří statisíce řádek kódu, dvacítka příruček, desetitisíce automatických testů, tisíce uživatelských scénářů pro akceptace a školení, za projektem jsou léta vývoje, používá se poměrně velká sada kompatibilních technologií s popsaným způsobem vazeb ...
Pepa je senior, projekt vede pět let, možná nerozumí všemu, ale přinejmenším ví, "že to tam je", a po deseti minutách se umí zorientovat. Franta je též senior, firma ho zrovna přijala, má léta praxe, všechny používané technologie "má v malíčku", má taky dvojnásobný plat než Pepa.

Stejný úkol

Přesto když ti dva dostanou stejný úkol, Pepa ho má do hodiny vyřešený, Franta pravděpodobně něco rozbije. Manažer se zlobí, začíná pochybovat o tom, že přijetí Franty bylo správné. Možná ho přeřadí na jiný projekt, kde se to zopakuje. Nebo to Frantu nechá opravit a dodělat, a rozčiluje se, že místo jednoho dne, který dostal s velkou rezervou, je to už týden.
První problém totiž je, že práce nováčka se nedá odhadovat bez ohledu na jeho léta praxe na jiných projektech.

Samouk

Další zlá varianta - tým má už tak málo lidí, že Pepa nemá čas na nováčka v týmu, každý den hasí "požáry". V rychlosti na něj každý den vychrlí nové informace, nemá čas ale vysvětlovat podrobnosti. Frantu hodí do vody, ukáže mu jak plavat, a dál ať to zkouší sám. Výsledek? Utekl měsíc, Franta je stále mimo, nefunguje mu už ani editor, nechápe proč. Nadává, co je tohle za firmu. Manažer vynadá Pepovi, ten ho nevrle pošle "do lesa".

Jinak a lépe

Nejefektivnější způsob zaučování je párové programování. Prostě si spolu musí aspoň na půlku pracovní doby sednout, Pepa bude navigátor, Franta řidič. Občas může být problém Frantovo ego, ale to už je na tom, jestli nový člen týmu zapadne do kolektivu. Samozřejmě mandays běží dvojnásobným tempem, ale čert je vem. Postupem času bude Pepy třeba méně a méně, při přechodu na další odlišnou práci si zase spolu sednou a dělají spolu.

Každý je nahraditelný ...?

Je? Není? Ale jo, je ... ale je třeba zvážit, za jakou cenu, přičemž cenou je tu hlavně čas (že čas nejsou peníze, vysvětlím dále). Někteří lidé prakticky nejsou v přijatelném časovém horizontu nahraditelní jedním člověkem - je třeba si rozmyslet, kolik a jaké práce běžně odváděli, v jaké kvalitě i kvantitě (to je další problém - jak to měřit?), a ideálně dostatečný počet nových lidí přibrat do týmu dříve než dotyčný odejde. I tak dojde ke zpoždění, protože je bude třeba do vývoje "dostat".

Opět - Pepa není ekvivalentem pěti Jindřichů ani padesáti Karlíků. Vyplnit vzniklou mezeru může být velmi těžké a pro celý tým stresující, čili je třeba, aby mezera byla co nejmenší, ideálně aby vznikl překryv. Pepa si nové lidi sám zaškolí.

Struktura týmu

V ČR je bohužel zažitá praxe, že organizace firem je hierarchická, někdy dokonce s mnoho patry. Kupodivu to většinou nefunguje, nebo to přinejmenším nefunguje hladce.
Druhý nešvarem je, že firmy týmy dimenzují spíše tak, že týmu jeden člověk chybí než aby jeden člověk přebýval. Tým pak nemá žádnou rezervu na řešení náhlých problémů, výzkum alternativ, atd. Tento přístup je přímo sebevražedný.

V týmu by měli být lidé sobě rovnocenní a měli by si rozdělit práci tak trochu podle vlastních preferencí a specializací. Projektový manažer nesmí být víc než vývojář ani naopak, oba by se měli ale vzájemně respektovat, oba jsou potřebnými a rovnocennými experty, každý na svou oblast.
V týmu si lidé musí vyměňovat názory, klidně se můžou i hádat, ale nesmí sebou navzájem pohrdat nebo se sebe bát v žádném smyslu slova.

Plánování práce

Předem píšu, že se stále bavíme o velkých zakázkách, řádově stovky až tisíce mandays.
Zákazník jen málokdy dodá kompletní specifikaci toho, co chce. Ve smlouvě je často jen název zakázky, cena. No a protože je třeba nějak specifikovat, za co že ta cena vlastně je, stanoví se nějaký počet mandays na základě velmi hrubé analýzy toho, co všechno bude obsahem zakázky.
Tato hodnota smí být užita nanejvýš orientačnímu porovnání s jinými zakázkami, a to ještě s velkou opatrností, nebo k orientačnímu rozdělení zakázky na fragmenty. Jinak je k ničemu a pokud jí k něčemu použijete, nedivte se, že vám pak nic nebude vycházet.

No dobře, když ale nemůžeme používat mandays, jak máme plánovat? Hned na začátku by měly být jasné dva údaje:
  • termín
  • rozpočet
A od nich a na základě nějakého interního rozboru analýzy odvodit strukturu týmu, jaký bude na implementaci nasazen, pokud možno plným úvazkem, jelikož přepínání úloh při tvůrčí činnosti unavuje, zdržuje, a tato režie sama zabila nejeden projekt. Výjimkou můžou být lidé, kteří neprogramují, ale jsou zapotřebí například pro údržbu serverů, podporu týmu. O těch nemluvím, ale i na ně je třeba v rozpočtu myslet.

Jakýchkoliv sledování nebo nedejbože plánování mandays se v tuhle chvíli vzdejte, jen by celý tým mátly, ale žádný užitek z nich nebude. Pamatujte, nemůžete házet na jednu hromadu Pepy a Franty, ne, ani Petra!
Můžete definovat mezitermíny dokončení "milestones" (tj. částečná implementace, která se dá považovat za hotovou část celku, a dá se například předat zákazníkovi k "osahání") včetně plánu rozpočtu, což se dá snadno a poměrně přesně průběžně kontrolovat.

Po rozjetí projektu (ne nutně po podpisu smlouvy, ale s rizikem, že k němu ani nedojde je třeba vždycky počítat), je v první řadě třeba zpřesnit analýzu tak, aby se dalo začít programovat. Není třeba udělat všechno najednou, ale je třeba mít analýzu konzistentní, abyste se netočili v kruzích.
Programování pak probíhá ideálně v iteracích, co iterace, to nějaká sada dobře naplánovaných úloh, za každou úlohu nese někdo odpovědnost, po každé iteraci se vyhodnocuje stav a případně se úloha posune do další iterace.

Toto je už věc analytiků, programátorů, manažer může přihlížet, vznášet dotazy, ale do organizace práce ostatních členů týmu by neměl nekvalifikovaně zasahovat, rozhodně ne autoritativně. Měl by ale naopak průběžně informovat programátory o stavu rozpočtu a celý tým by měl dokázat zhruba odhadnout procento implementace vůči nejbližšímu plánovanému milestone.

Definice úlohy

Definici úlohy specifikují typicky programátoři ve spolupráci s analytikem. Úloha by měla mít následující atributy:
  • Název - jednoduchý a srozumitelný alespoň všem programátorům
  • Popis - co nejpečlivější a hned na začátku rozšířený o slovní návrh implementace, plus způsob ověření funkčnosti
  • Termín - u úlohy do nejbližší iterace už závazný, u úlohy plánované na později spíše orientační
  • Pracnost - odhad programátora, spíše pesimistický než optimistický. Všichni budou šťastní, pokud se to povede napoprvé, ale málokdy se to stane. Pokud je úloha ale dokončena s nižší než odhadnutou pracností, je to pořád dobré.
  • Specifikace závislostí na jiných úlohách
Právě součet pracností úlohy je pak použitelný k dalšímu odhadu toho, zda se vše stíhá, nicméně je nutné počítat i se závislostmi a vytížeností týmu, což není tak jednoduché, jak se na první pohled zdá. Pokud to zanedbáte, riskujete, že si až pozdě všimnete, že nestíháte. Na druhou stranu, plánovat příliš podrobně příliš dopředu vás také nikam neposune, jen ztratíte čas něčím, co pak buď budete zbytečně udržovat, nebo co stejně vyhodíte.

Čas nejsou peníze

Prostý fakt je ten, že zákazníka nezajímá, kolik lidí jste ve skutečnosti v týmu měli ani kolik tým strávil "mandays" prací na díle, dokonce ani jestli jste zaměstnali dvacet čerstvých absolventů vysoké školy nebo dva specialisty za 200 tisíc měsíčně. To je věc dodavatele, aby zvolil nejlepší cestu.

Ano, zákazník se může snažit zjistit, jaký máte zisk, resp. o kolik levnější daná zakázka mohla být. Pokud vás ale chce usvědčit z toho, že jste ho obrali, stejně vám při nejbližší příležitosti uteče, a svědčí to mimo jiné o tom, že jste nějak podcenili komunikaci se zákazníkem - začal vás podezřívat.

Zákazníka hlavně zajímá to, aby dílo, které zaplatil, nemělo žádné vady a fungovalo tak, jak požadoval. Mandays používá spíše na "virtuální" ohodnocení pracnosti díla. Toto číslo ale nemá s realitou interních výkazů práce nic společného. Kdyby mělo, představte si to - zákazník má problém, tak za ním pošlete:
  • experta, který je za dvě hodiny hotový
  • sekretářku, která zavolá expertovi, který jí naviguje. Dílo též skončí po nějakých čtyřech hodinách úspěchem
Vážně si myslíte, že můžete vyfakturovat celý jeden manday (2 lidi krát 4 hodiny)?*
Krom toho plat sekretářky je jen zlomek toho, co bere expert. Seriózní firma samozřejmě vždycky pošle experta. Tento příklad se obvykle řeší smluvně trochu jinak, ale jako okatý příklad nesrovnalosti takového přístupu snad stačí.

Závěr

Jinak řečeno, ano, asi jste si už u svých velkých zakázek všimli, že se nedají moc dobře plánovat. A právě proto vznikly termíny jako agilní techniky vývoje software, extrémní programování, a další, viz oba odkazy. Pro manažera, zvyklého na vodopádový model (pokud vůbec), je to celkem nepříjemná změna, ale je to jen o zvyku - nakonec je naopak příjemné, že se pořád něco děje a pořád se to posouvá, a když po každé iteraci vidí hotové dílo, už by neměnil.

Ještě bych zmínil jeden web, http://wiki.c2.com, vypadá sice triviálně a zastarale, ale obsahuje neskutečné množství nadčasových otázek a odpovědí, týkajících se vývoje software, vysvětlených podle mého soudu celkem srozumitelnou formou včetně různých pastí. Pokud ho začnete vážně číst, je možné, že budete mít problém přestat ...

P.S.: Kniha The Mythical Man-Month byla vydána v roce 1975.

EDIT: Na základě připomínky kamaráda, vztahující se k článkům "Agile is Dead" (které si najděte sami), přidávám ještě jeden odkaz s reakcí na ně: Is the Agile Manifesto Dead?
Stručně řečeno jde o to, že se z Agile stal buzzword, obchodní značka, přičemž původně šlo spíše o apel a nějaký soupis technik, které při vývoji pomáhají. "Agilní" znamená česky "snaživý", tak se snažte dělat věci dobře, chovejte se jako tým, atd. Ne, neznamená to, že se budete doslovně držet nějakého seznamu bodů. Myslete. A mluvte spolu.

*) Pro puntičkáře - zatímco sekretářka cestovala, expert se už připravoval na její podporu a studoval logy, které dostal.

sobota 17. května 2014

Refaktoring, část II.: Technický dluh

Aneb kapitola (nejen) pro manažery, ekonomy, zkrátka byrokracii, která rozhoduje o investicích, financování, směrování projektů - a taky o tom, kdy se projekt uzavře jako "hotový".
Původně jsem chtěl jít rovnou na zdrojáky, ale událo se něco, co mě přimělo vložit ještě jednu kapitolu. Zjistil jsem totiž, že u nás se o technickém dluhu až zase tak moc nemluví. Nicméně programátorší "guru" o této metafoře mluví už docela dlouho:

Co je to?

Manažeři i zákazníci milují vodopádový model: objednávka, zadání, analýza, zhotovení, akceptace, zaplacení. Nic složitého to přece není, vypadá to triviálně a jednoznačně. Ti zkušenější už ví, že každá ta fáze skýtá mnohá nebezpečí a pasti. Obecně nejednoznačnost a nedotažení každé té fáze - příčinou je obvykle neznalost přesných požadavků a neznalost způsobu výroby na druhé straně.

Zjednodušeně řečeno, technický dluh vzniká vždy, když kdokoliv na projektu odloží něco, o čem dobře ví, že je třeba udělat, ale odloží to - ať už se to týká analýzy, testů, dokumentace, vyčištění kódu.

Jak moc to vadí?

To je různé - asi jako inflace, státní dluh, vaše dluhy; proto se tomu říká technický dluh. Jsou to nedodělky, ale ne jen ty, které vidíte při předvádění aplikace. Ty skryté jsou daleko nebezpečnější. Proč? Nedodělky, které vidí uživatel, viděli všichni během vývoje projektu, a došlo k nějakému konsenzu, že jde o kompromis, se kterým uživatel dokáže žít.
Nedodělky, které ale vidí jen programátoři (pokud je vůbec někdo vidí), mají vlastnost právě té inflace - je to exponenciální funkce. S každou další iterací se umocňuje vliv dluhu, veškerá jeho negativa. Dlouho to nemusí vadit, ale když nad technickým dluhem ztratí vývojový tým kontrolu, už není cesty zpět a vývoj projektu skončí s potupnou ztrátou a obviňováním všech, kteří se na něm podíleli, navzájem.


Exponenciální funkce

Je jasné, že udržet projekt bez dluhů je prakticky nemožné. Vždycky se dá všechno udělat lépe. Na druhou stranu, když dluhy nesplácíte, špatně skončíte. Z vlastní praxe bych to rozdělil na takové tři kategorie (v horším případě fáze) ...

Dluh pod kontrolou

Dobrý stav, který znamená, že projekt má budoucnost a přestože obsahuje pár chyb (někdy i hodně), má smysl v něm pokračovat. Příznaky jsou následující:
  • vývojáři dávají celkem rozumné odhady pracnosti
  • nikdo není nervózní, panují dobré vztahy
  • vývojáři se těší na další úkol
  • většinou se stíhají termíny

Zadlužení

To už je horší stav, ale není nezvladatelný. Nesmí se podcenit - i za cenu oddálení termínu předání další verze je nutné dluh udržet nebo ideálně snížit. S každým dalším nárůstem se situace zhoršuje. Příznaky tohoto stavu jsou takové:
  • vývojáři pracují přesčas, často neplaceně a dobrovolně
  • zpravidla se nestíhají termíny, předání verze se oddaluje i opakovaně
  • často se mění analýza během vývoje
  • množí se požadavky na "až"
  • horší se přesnost odhadů pracnosti - obvykle se podstřelují v toužebné snaze všech stihnout termín
  • tendence přidávat lidi do zpožděného projektu
Management nechápe, proč se dříve termíny stíhaly a teď ne, má tendenci přitlačit, motivovat, ale prakticky dosahuje jen jediného - zvýšení tlaku a stresu, což často končí odchodem zaměstnanců, zpravidla těch nejlepších v první řadě, těch nejhorších potom v řadě druhé. Zůstávají jen bojovníci - pokud se dokážou vzepřít veškeré nepřízni, má projekt ještě naději.

Exekuce se blíží

V tuto chvíli se podívejte opět na ten graf exponenciální funkce. V určitém bodě se dostanete přes hranici, kdy vývoj dalších verzí projektu stojí ohromné zdroje a úsilí a jste ve stavu, kdy je extrémně těžké s tím něco začít dělat.
  • vývojáři často mění své odhady, klidně o dva řády - z hodiny je týden, z týdne 20 minut.
  • jakýkoli termín vyvolává šílený smích vývojářů
  • panuje nervozita a dochází k hádkám a práskání dveřmi
  • manažeři zakazují jakoukoliv údržbu, dovolené, a snaží se do projektu dostat nové lidi - a to jakékoliv
  • neprovádí se analýza, nebo jen povrchně
  • nehledí se na žádná kvalitativní měřítka
Je téměř vyloučeno, abyste se dostali z této fáze zpět. Pokud chcete v budoucích projektech uspět, uvědomte si, co jste zanedbali dříve, podcenili. Není to o tom, že jste měli požadovat vyšší cenu nebo sehnat více lidí.  Vždy potřebujete čas a vždy potřebujete nějakou stabilní kvalitu. Na tom, co děláte dnes, budete stavět zítra.

Udržování dluhu pod kontrolou

Všechno je vlastně docela snadné a pro řadu souvisejících problémů dokonce existují nástroje.

Odhadování pracnosti

To je problematika, na které často stojí váš úspěch - odhadnout, kolik času budete potřebovat na zhotovení něčeho, o čem ještě nemáte "ani páru", je trochu neřešitelný úkol. Existuje na něj řada strategií a doporučení, ale vždy ke kvalifikovanému odhadu potřebujete přehled. Odhad navíc nemůže být definitivní - je to jen odhad, že ...

P: "Devět žen neporodí ani jedno dítě za jeden měsíc. Chápeš?"
M: "Jojo, tohle ví každej, to znám ... Ale Ty jsi chlap!"
P: "Máš pocit, že devět chlapů nějaké dítě porodí?" 

Jak se projevuje technický dluh na odhadu? Představte si, že máte nějakou knihovnu, kterou lehce zanedbáváte - používáte jí ale v aplikaci bez problémů. Přijde ale nový úkol pro aplikaci, při kterém ale zjistíte, že v knihovně je chyba. Také zjistíte, že chybu jste v jiných aplikacích, které na ní už narazily, obešli. Jenže tuto obezličku v nové aplikaci uplatnit nemůžete, protože je v rozporu se zadáním - a navíc jste tehdy nepsali ani testy, takže ani nevíte, co všechno se opravou naopak rozbije.
A tak vám nezbude, než chybu opravit, čímž ale možná rozbijete již hotové aplikace s obezličkou. Tudíž pak budete muset i dopsat testy a opravit i tyto aplikace.

A teď se krátce zamyslete - jaký asi byl původní odhad? Kolikrát ho během opravy změníte? A jaká byla výsledná pracnost? Tím to ale nekončí - opravené aplikace bude možná třeba také distribuovat, takže nám vzniká další pracnost.
Ufff, tohle bolelo. A ještě bude, protože všem musíte vysvětlovat, co se vlastně stalo a proč - a čas běží dál a náklady rostou.

Psaní automatických testů

Automatický test je vlastně další kód, který programátor napíše nejlépe předtím, než začne programovat nějakou funkcionalitu aplikace. Test není součástí aplikace, ale verzuje se spolu se zdrojáky, a moderní programovací jazyky velmi pečlivě zohledňují testovatelnost.
Není žádná výmluva pro nepsaní testů, nikdy. Už dobrých 20 let se považuje za prokázané, že automatické testy vedou k
  • rychlému nalezení chyb nového kódu
  • ujasnění designu a zpětné vazbě analýze dříve, než je aplikace hotová
  • rychlému nalezení chyb, které způsobily opravy na jiném místě
  • konzistentnímu refactoringu (nic se nerozbije)
  • dokumentaci funkcionality (test minimalisticky ukazuje, jak se funkcionalita používá)
Naopak prosby nebo dokonce zákazy manažerů, aby se psaní testů odložilo, protože není čas, končí tak, že
  • dostanou funkcionalitu ještě později
  • druhý den se opravuje oprava dne předchozího, den za dnem
  • nikdo neví, co to vlastně dělá a k čemu to je (brzy ani autor)
  • jakákoliv změna v kódu znamená nutnost manuálního přetestování skoro celé aplikace, protože nikdo neví, co všechno změna ovlivnila

Refactoring

Refactoring se přímo zaměřuje na snižování technického dluhu. Obvykle je dobré začít psaním testů, dopisováním //FIXME a //TODO, případně komentářů, kam si zapíšete své objevy proč a co se v tom daném místě děje, co je na tom špatně, jak by to mělo být správně. Tyto komentáře neslouží k tomu, aby v kódu zůstaly, ale abyste se při své analýze neztratili.
Musíte postupovat opatrně, protože se pohybujete na "minovém poli" (proto kód chcete přece refaktorovat), a krok vedle může znamenat, že své úpravy zahodíte (dokud je ještě čas).

Refactoring předně slouží k tomu, aby byl kód čitelný, měl jasné odpovědnosti a funkcionalitu, choval se předvídatelně a funkcionalita byla vždy k nalezení tam, kde jí člověk hledá. Potom se na kódu teprve dá stavět něco dalšího, kde nebudete muset vymýšlet žádné obezličky.

Refactoring nikdy nekončí - ke každému kódu se po čase musíte iterativně vracet, protože jak se rozvíjí aplikace, je občas třeba změnit trochu i uspořádání kódu, sloučit věci, které se původně zdály rozdílné, ale nejsou, rozdělit věci, které původně dělaly téměř totéž, ale už dávno to není pravda, atd.
Ač se to některým lidem zdá pořád neuvěřitelné, nečitelnost kódu, velké množství duplicit a slabé pokrytí testy mají extrémní vliv na jakýkoliv budoucí rozvoj, daleko větší než sebekomplikovanější zadání.

... a odkládání

Pokud se údržba zanedbává, problémy na sebe nenechají dlouho čekat:
  • náklady na rozvoj aplikace jsou čím dál vyšší, neúměrně požadavkům zákazníka
  • opravené chyby uživatel opět hlásí jako neopravené (našel je i jinde)
  • aplikace se chová nekonzistentně (a uživatel jí nenávidí)
  • aplikace potřebuje více paměti a je pomalá
  • vývojáři trvá velmi dlouho, než zjistí, co má vlastně dělat, těžko se orientuje
  • n testů téže věci a podobná věc není otestovaná vůbec
  • nepřehledná dokumentace, nepřehledné testy, nepřehledná aplikace
  • vývojáři nenávidí aplikaci a po čase odchází jinam (nepodceňovat!)
Často se ale zapomíná také na to, že jsme jen lidé a zapomínáme. O týden odložená údržba už znamená, že se v ošklivém kódu přestává orientovat i jeho autor, a nejen rozvoj aplikace, ale i její údržba stojí více, je namáhavější a také při ní pravděpodobně vznikne více chyb.Je to podobné jako s úvěry - u některých můžete odložit několik splátek, ale pak je bude mnohem těžší dohnat. Možná to už nezvládnete ...

Nástroje

Co se týče sledování odhadu technického dluhu u nás používáme SonarQube; V této aplikaci je i řada dalších metrik kvality software a dá se říct, že je to jediná aplikace, kterou znám, která umí zobrazovat i historii různých hodnocení projektů a dá se i zhruba použít k porovnávání kvality. Podotýkám, zhruba, protože žádný software nemůže posoudit to, jak vaše aplikace plní požadavky uživatele a zákazníka.

No a pokud jde o nástroje pro vývojáře a tvorbu automatických testů, refactoring a vývoj obecně, ti už "ty svoje" nástroje určitě dobře znají ;-)