Tento příspěvek je krátkou obhajobou dekompozice složitých problémů na malé koncové tasky. Práce s malými tasky totiž působí přímo blahodárně na často dost zatížené nervové soustavy členů projektového týmu. Pokud se váš projekt zasekává a dostává se do vážnějších problémů, zkuste se zamyslet nad tím, zda-li nebojujete s problémy, které jsou typické pro nezvládnutí správné dekompozice složitosti.
Malý task
Co je vlastně myšleno malým taskem? Pro mě je to task s dobou realizace do 4 hodin, ale ideálně kolem 2h. A nezávisle na tom, zda-li se jedná o práci analytickou, návrhovou, implementační, testování nebo úkoly spojené s podpůrnou infrastrukturou projektu a byrokracií (paper work). Velikost commitu v případě implementačního tasku by neměla překročit řádově desítky změněných řádků (počítáno jako LLOC). Na druhou stranu je počet změněných řádků kódu dost zavádějící metrika. Někdy můžeme půl dne hledat bug a výsledkem je změna na jednom řádku (+ nový původně padající test). Jindy děláme refaktoring a jeden rozsáhlejší rename vynutí změny na stovkách řádků.
Ne vždy se to podaří ...
Rozložení řešeného problému na malé postupné krůčky je efektivní a univerzální technika ve všech oborech lidské činnosti. Ve vývoji software je ale nutné mít vhodné podpůrné nástroje a efektivní postupy. Jinak se dobře míněná snaha o zvýšení efektivity práce změní ve znechucené trápení. Je nutné zajistit splnění několika základních podmínek:
- Pracovní postupy by neměly být zatíženy přílišným formalismem. Čím méně restriktivních opatření, tím lépe. Příliš formální metodiky jsou účinnou antikoncepcí proti vytváření malých tasků. Předpokládám, že agilita si vybojovala místo i ve vašem vývojovém týmu a proto bude tato podmínka bude splněna.
- Používejte nástroj, který vám usnadní správu a vizualizaci tasků. Protože jsou malé, je jich také mnoho. Nástroj musí být intuitivní, rychlý a dostupný bez omezení. My jsme se rychle spřátelili s YouTrackem, který pro naše potřeby maximálně vyhovuje.
- Vytvoření tasku musí být rychlé. Vybrat umístění (projekt, feature nebo user story), zadat název, stručný popis, akceptační kritéria a estimaci. To by mělo ve většině případů stačit. Někdy se při vytváření tasku zasekneme, neboť napsat dobré zadání je pracné. Ale zdržovat by nás mělo pouze naše myšlení a ne použitý nástroj.
- Používejte pouze atributy, které potřebujete. Šablona tasku, která má desítky atributů je dobrá obvykle jen pro někoho, komu potřeba projektové formalizace způsobila neléčitelnou ztrátu zdravého rozumu. V jednoduchosti je síla, proto nejdůležitější položky musí být dostupné rychle, bez nutnosti překlikávání. Méně využívané položky by pak měly být schované na detailových kartách. A nepoužívané bez milosti odstraněny. Dvakrát si rozmyslete, než přidáte nový atribut.
- Workflow tasku musí být jednoduché. Čím méně stavů tím lépe. Na našem posledním projektu jsme zvolili tyto: Backlog, Ready for Dev, Dev in Progress, Ready for Review, Review in Progress, Finished (+ Waiting) s vizualizací pomocí Kanban boardu. Pokud bychom neměli interní politiku o revidování každého tasku, pak bychom ještě dva stavy ušetřili. Některé typy tasků ale jedou v jiném režimu, např. task typu Bug nahlášený od testerů nebo v horším případě z produkce.
- Mělo by být možné integrovat systém pro evidenci tasků s dalšími články vývojové infrastruktury. A to se správou repository, buildovacím serverem, IDE, CASE, apod. Např. k namapování změn v kódu na příslušný task pak pouze stačí odkazovat id tasku v commit message.
Ale když se to podaří ...
A v čem jsou vlastně malé tasky šikovnější než ty velké obludy?
- Rychlé vyřešení tasku působí blahodárně na psychiku a dobrý pocit z dokončení je účinným motivátorem do další práce. Rozplizlé dlouhé tasky nás naopak demotivují, nevidíme na jejich vzdálený konec a vnášejí pochybnosti o naší pracovní efektivitě. Tak jako většina lidských činností je i vývoj software psychologickou hrou s naším podvědomím, snahou udržet nadšení, pozornost a správný kurz k požadovanému cíli.
- Menší jednotky práce je snadnější přesně specifikovat. Problém jsme nuceni už při zadávání lépe promyslet a zadefinovat akceptační kritéria. Dobrým zadáním problému zvyšujeme pravděpodobnost správné realizace a efektivního review.
- Přesnější estimace. Je dost deprimující, když se skutečná pracnost na hony liší od té odhadované. Malé úkoly trefíme mnohem lépe. Doporučuji mírně pesimistický přístup a zohlednit časovou rezervu. Udělat úkol dříve než se čekalo je povzbuzující. Máme ze sebe dobrý pocit a roste nám správným způsobem sebevědomí. Naopak výrazné přešvihnutí estimace nás dostává pod tlak, který často vyústí ve sníženou kvalitu výsledku.
- Review menších změn je mnohem efektivnější. Je zřejmé, na co se zaměřit. Review trvá kratší dobu, takže reviewer je pozornější, neusíná a často i něco objeví.
- Stává se méně často, že odcházíme domů a zůstane po nás nedokončený úkol. Já osobně nemám tyhle situace vůbec rád a když něco nedotáhnu do konce, přemýšlím nad tím ještě doma. A nejhorší je nedotahovat věci v pátek odpoledne.
- Pokud zaneseme chybu nebo rozbijeme CI build, pak je problém mnohem lépe dohledatelný. Je rozdíl, pokud hledáte v commitu s 20 změněnými řádky nebo s 200.
- Dostáváme rychlejší zpětnou vazbu a pokud se něco nepovede, nevracíme se příliš daleko dozadu. Víme, jak je nepříjemné zahodit kód, nad kterým jsme strávili dlouhé hodiny nebo dny. Obvykle je ale výhodnější špatný kód zahodit, než obhajovat jeho smysluplnost a tím jeho eutanázii pouze oddalovat a zvyšovat tak náklady na vývoj.
- Malé tasky vnášejí do vývoje větší dynamiku a celý tým může sledovat postup řešení většího celku, třeba user story. Nestává se, že programátor dostane zadání, pár dnů o něm nevíte a pak se objeví s “vymazlenou” implementací, která se ale hodně odklonila od původního záměru a trpí mnoha nedostatky.
- Jistě znáte techniku TDD, která nabádá ke krátkým implementačním cyklům se strukturou: 1. rozmysli si co chceš (napiš test), 2. naimplementuj to (napiš produkční kód), 3. zkontroluj, jestli změna nerozbila celek (všechny testy zelené), 4. vylepši fungující implementaci (refaktoring). Díky TDD dostáváme okamžitou zpětnou vazbu o stavu našeho kódu. Malý task by pak v tomto chápání mohl mít podobný efekt jako cyklus TDD, ale s větší granularitou. Nutí nás více rozmýšlet požadovaný výsledek, ten dostáváme již během několika hodin. Po uložení změn do repository získáme skrze CI build informaci o stavu celku. V rámci review můžeme řešení ještě vylepšit.
S malými tasky můžeme dosáhnout velkých výsledků. A navíc velmi efektivním způsobem. A za každé dokončení tasku se můžeme nějak odměnit. Třeba procházkou k lednici, krátkou rozcvičkou nebo dobrým kafem. A život programátora bude zase o něco veselejší! ;)