Jak na technický dluh (technical debt)

Technický dluh (z anglického technical debt) definoval Ward Cunningham v roce 1992. Použil metaforu z finančního světa. Ve finančním světě si půjčíte peníze a počítáte s tím, že je někdy splatíte. Po dobu výpůjčky vám z půjčených peněz běží úrok a vy musíte vracet půjčenou částku i s úrokem. Když máte půjčeno na dlouhou dobu a nesplácíte, tak úroky nabíhají a dluh tím narůstá.

Při vývoji software si také někdy půjčujeme. Ne však peníze, ale někdy z dobrých důvodů obětujeme vnitřní strukturu produktu, abychom mohli produkt rychle dodat na trh. Předpokládáme, že až bude produkt úspěšný, tak to zaplatí nejenom vývoj nových funkcí ale i zlepšení zanedbané vnitřní struktury.

Tady ovšem nastává drobný rozdíl. Zatímco ve finančním světě se dluhy (obvykle) platí, ve světě vývoje software je vždycky spousta důvodů k domu, aby se “splátka dluhu” neboli vylepšení vnitřní organizace produktu odložilo, protože firma teď zrovna potřebuje dodat důležitou novou funkci na trh a nemůžeme si dovolit žádné zpoždění. Tím vzniká začarovaný kruh technického dluhu.

začačarovaný kruh technického dluhu (vicious circle of technical debt)

Nemáme čas na vylepšení vnitřní struktury. Tím pádem nám ubývá čistého kódu. Proto trvá dlouho vyvinout nové funkce. Byznys ale potřebuje nové funkce rychle. Proto tlačí na vývoj funkcí a upozadění technických aktivit, které by vylepšily vnitřní strukturu. Pokud v tomto režimu jede vývoj software několik let, vláčí sebou vývojáři obrovskou historickou zátěž při psaní nového kódu. A firma má zaděláno na pořádný problém, který často vede až ke kompletnímu přepsání produktu do nové technologie a celý cyklus se začíná opakovat.

Technický dluh ale vzniká i v produktech, které jsou zodpovědné a pravidelně investují do jeho vylepšování. Technologie se průběžně mění a zdrojové kódy musí udržovat krok. Máte napsaný backend v djangu 3.2? Technická podpora skončila v dubnu 2024. Napsali jste produkt v době, kdy neexistoval docker a kontejnery? Teď ho ale potřebujeme provozovat v kubernetes clusteru. 

Co se s tím dá dělat? 

Předně si řekněme, že neřešit technický dluh inkrementálně a přepsat celý produkt odznovu je legitimní strategie. Slyšel jsem o jenom nejmenovaném e-shopu, který má svůj obchodní software napsaný v Delphi. V takovém případě může dávat smysl začít znovu.

Stejně tak, když víme, že produkt už dožívá, nemá smysl do něho příliš investovat. Pokud víme, že životní cyklus produktu končí za méně než dva roky, technical debt už nemá moc smysl řešit.

Pokud se rozhodneme náš produkt inkrementálně vylepšovat, tady je několik tipů, jak to udělat, abychom úspěšně propluli mezi nekonečnými požadavky byznysu a frustrací developerů.

Udělat z postupné změny součást firemní kultury

K tomu potřebujete vzdělané vývojáře, kteří vědí, jak dělat inkrementální změny v ošklivém kódu. Práce s legacy kódem je dovednost, která se nedá  naučit ve škole a mnohdy ani ve firmách (viz výše, mnoho firem technický dluh spíš ignoruje). Proto je vhodné svoje programátory v tomto směru cíleně vzdělávat.

Zároveň je potřeba přestat tlačit na termíny nebo odstínit vývojový tým od tohoto tlaku. Vývojáři často vědí, co by měli dělat, ale cítí tlak z byznysu a podlehnou mu v naději, že až doděláme tuhle urgentní věc, budeme mít konečně čas na to přepsání, Nebudeme. Je to zodpovědnost manažera, aby jim dal takový prostor, aby mohli profesionálně vykonávat svoji práci. Na chirurga taky vedení nemocnice netlačí, že má při operaci zrychlit.

V praxi to může vypadat tak, že tým si vyhradí například 10% času na opravy technického dluhu. Pokud týmy používají Scrum, můžete zavést pravidlo, že jednu položku do sprintu si týmy dávají samy nezávisle na prioritách, které přijdou shora. Ale pozor, pokud nevyřešíte předchozí bod (tlak na termíny), tak toto opatření nepomůže – vývojáři budou tlak stejně cítit a “zbytečnou” práci odloží na později.

Refactoring znamená malé krůčky

Součástí vzdělávání a firemní kultury musí být i refactoring. Často se zmiňuje tzv. skautské pravidlo (boyscout camp rule): Nechej tábořiště v lepším stavu, než v jakém bylo, než když jsi na něho přišel. V případě kódu to znamená: pokaždé, když sáhneš do nějakého kódu, zkus ho trochu vylepšit. Nemusíš ho přepsat tak, aby byl dokonalý. Stačí, když po tvém zásahu bude trochu lepší, než byl předtím. Když to tak budou dělat všichni dost dlouho, tak se bude kód postupně zlepšovat.

Pozor! Slovo “refactoring” používají někteří programátoři velmi volně a myslí tím jakýkoliv přepis kódu, který se jim nelíbí jakýmkoliv způsobem včetně zahození původního kódu a kompletního přepsání. To ale není refactoring nýbrž redesign nebo rewrite. Refactoring má přesnou definici: změna struktury kódu bez změny jeho funkce a typicky se děje v miniaturních krůčcích, např. přejmenování proměnné, extrakce kousku kódu do metody. Měl by být běžnou součástí práce každého developera a není k němu potřeba žádné zvláštní povolení. Když tedy uslyšíte “management nám nechce dovolit refaktorovat”, víte, že dochází ke zmatení pojmů.

Malé změny udělejte hned, velké patří do backlogu

Malé změny v rozsahu skautského pravidla je vhodné neodkládat a řešit jako součást práce na nejnovější funkci pro byznys. Ano, vývoj nové funkce se tím trochu prodraží, ale vy tím metaforicky zaplatíte kousek dluhu a zbývající úrok už nebude tak vysoký neboli vývoji nových funkcí bude zase o něco rychlejší.

Velké iniciativy ovšem patří do backlogu a měly by projít prioritizací úplně stejně jako nové funkce důležité pro byznys. Platí, že čím je technická iniciativa větší, tím jednodušší bývá najít přínos v penězích a tím pádem se lépe porovnává s psaním nových funkcí. Pár příkladů:

  • převod našich serverů do AWS – ušetříme na provozu serverů, protože špičkovou kapacitu potřebujeme jenom v předvánočním období
  • napsání frameworku pro automatizované testy – automatizované testy sníží chybovost a frustraci zákazníků. Navíc nám umožní snížit podíl manuálních testů, které se musí opakovat pořád dokola a musí je dělat člověk, který je drahý.
  • přechod z .NET 6  na .NET 8 – ve starším .NEtu jsou bezpečnostní díry, které jsou opraveny až ve vyšší verzi

Co nefunguje?

Některé firmy se snaží snížit technický dluh tím, že organizují hackatony, “fix-it” days, “bug hunt” days, apod. Takový přístup může na chvíli snížit frustraci developerů, ale dlouhodobě ničemu nepomůže. Když totiž organizujete speciální “fix-it” den, tak tím vlastně říkáte: dnes je ten den, kdy se opravují chyby. A nevyřeno zůstává: všechny ostatní, běžné dny se chyby vyrábějí a neopravují. No a těch běžných dnů je mnohem víc, než těch speciálních.

Závěrem: technický dluh je složitý problém, se kterým se potýká každá firma, jejíž produkt má 2 a více roků. Není to ale nic nezvládnutelného. Není nutné dluh kompletně vymazat (to ani není možné), ale spíše ho držet pod kontrolou, stejně jako u finančního dluhu.

Ve své konzutační a školicí praxi vycházím z mnohaletých zkušeností s vývojem software. Používám techniky, které jsou v souladu s touto zkušností, i s principy agilního vývoje. Pokud se vám článek líbil, sledujte mě na LinkedIn nebo Twitter.

Napsat komentář

13 − 6 =