Când implementezi o nouă funcționalitate ai două opțiuni: (neagră sau albă) - repede și neglijent sau curat și inteligent. În primul caz se tot adaugă o datorie tehnică pe care vei fi nevoit să o plătești la un moment dat. Dacă alegi opțiunea a doua - investești initial mai mult timp și energie - dar devine mai ușor să dezvolți aplicația în viitor.
Proiectul la care am lucrat a pornit de la zero. Au fost momente când am fost presați de timp și sprint după sprint am început să acumulăm puțin câte puțin datorie tehnica. De obicei, la sfârșitul sprintului ne dădeam seama că ne-am supraestimat abilitațile de a livra noi funcționalitătți. La acel moment eram mult mai interesați în a livra cât mai mult și cât mai repede, în defavoarea calității tehnice. Feedback-ul din partea clientului pe partea de arhitectură a venit foarte tarziu, iar când a venit am realizat că parte din codul nostru nu respectă îndeaproape recomandările lui. Câteodată am livrat o funcționalitate care mergea corect din punct de vedere al businessului, dar codul din spate era slab structurat.
Ne place ideea de arhitectură emergentă în care structura aplicației se dezvoltă pe măsura ce proiectul evoluează. Pe măsură ce sunt implementate cerințele clientului arhitectura aplicației se dezvoltă și se cristalizează. E o modalitate bună de a lupta împotriva incertitudinii - atunci când nu știm de la început în detaliu toate cerințele sistemului, îl construim pe măsură ce aflăm răspunsul la întrebări.
Adăugând o componentă aici, alta dincolo, aplicația noastră a început să semene tot mai mult cu Frankenstein. Din punct de vedere al utilizatorului - aplicația făcea tot ce trebuia - dar codul a devenit pe zi ce trece tot mai greu de întreținut.
Un alt punct slab al echipei noastre era faptul că aveam o singură persoană specializată pe o anumită tehnologie - ca de exemplu Alex pe BPM. Când el era plecat în concediu,ceilalți membri ai echipei care au scris cod BPM, neștiind ce era acolo, au scris cod doar ca să meargă fără să înțeleagă în amănunt implementarea BPM. Acest lucru se numește efectul autobuz: de câți oameni e nevoie să fie călcați de autobuz pentru ca echipa să nu-și mai poată continua activitatea în mod normal. În cazul nostru efectul autobuz era egal cu unu. Pentru a înlătura această deficiență, am încercat să avem cel puțin două persoane care să știe codul care ține de o anumită tehnologie (în cazul BPM a fost vorba despre Cosmin și Ștefan).
Pe măsura ce încheiam un Sprint și încă unul, codul sursă al aplicației devenea tot mai dificil de întreținut. Tot ce am pus sub preș începea să iasă la suprafață. Dezvoltatorii nu mai erau capabili să scrie cod pentru o nouă componentă până nu puneau la punct codul existent. Soluțiile rapide aplicate în trecut au transformat codul în nisipuri mișcătoare.
Auzeam tot mai des la întâlnirile zilnice SCRUM: task-ul meu a durat de două ori mai mult decât a fost estimat pentru că a trebuit să sap și să refactorizez sistemul. Oamenii deveneau pe zi ce trece tot mai frustrați. Dezvoltatorii deveneau tot mai nemulțumiți pentru că petreceau mai mult timp să curețe codul existent decât să scrie funcționalități noi. Managementul s-a alarmat pentru că a scăzut velocitatea echipei. În același timp dezvoltatorii au început să stea tot mai mult peste program în încercarea disperată de a livra funcționalitătile promise la timp.
Pentru a gestiona User Story-urile și task-urile folosim atât tabla de SCRUM cât și Jira. Tabla de SCRUM e inima echipei noastre unde ne întâlnim și discutăm toate problemele. Folosim Jira pentru a oferi Product Owner-ului posibilitatea de a vedea evoluția proiectului (Product Ownerul se afla în altă locație decât locația echipei de dezvoltare). Pe măsura ce timpul trecea - Jira a devenit tot mai greu de gestionat datorită task-urilor neînchise, task-urilor neplanificate, modificărilor la User Story apărute între timp. Din Jira a devenit imposibil să-ți dai seama de starea proiectului. La un moment dat lucrurile au devenit atât de grave încât nu am mai putut continua să lucrăm așa.
Pentru că nu se mai putea continua așa - am scos totul la lumină: am pus datoria tehnică pe tabla agile și în Confluence. Partea cea mai grea a fost discuția cu clientul, să admitem că avem o problema și să-i cerem susținerea.
Am început prin a revizui întreaga arhitectură și întreg codul. Am extins utilizarea Sonar, intrumentul folosit de noi pentru controlul calitătii și Jenkins - care ne ajută la livrarea continuă.
Colegul nostru de la Endava Cluj - Mădălin - a mers un pas mai departe. A creat un panou care oferă o imagine de ansamblu asupra celor mai importanți indicatori de calitate. Și aceasta pentru toate echipele care lucrează la un același proiect într-un mod comparativ. După cum puteți vedea în imaginea de mai jos se pot urmări: numărul și tipul bug-urilor și trendul evoluției lor, acoperirea cu teste unitare a sistemului și rezultatul rulării testelor automate.
Sunt trei pași pentru a scapa de datorie (conform cursului de PSPO de la Scrum.org):
După ce am facut vizibilă datoria tehnică pe tabla de agile și în Confluence, am început să rezolvăm din ea puțin câte puțin în fiecare sprint. La un moment dat ne-am dat seama că în ritmul acesta se termina proiectul și noi nu terminam datoria tehnică. Așa că ne-am luat un sprint ca să o rezolvam. În același timp am încetat să ne mai împrumutăm.