Cosa tracciare (e come tracciarlo) mentre stai programmando

Cosa tracciare (e come tracciarlo) mentre stai programmando

Marco Bellezza Di Marco Bellezza


coding tracciamento

Eccoti lì, davanti ai sorgenti, alle prese con un blocco di codice che proprio non riesci ad interpretare. Vorresti poter entrare nella testa di chi l'ha scritto, o più ironicamente ripercorrere cosa tu stesso avessi in testa quando l'hai scritto.

Purtroppo, non esiste (ancora) una tecnologia che ti possa far esplorare la cronologia dei tuoi pensieri, né di quelli altrui. Fino ad allora, dovrai predisporre manualmente quella cronologia.

Stiamo parlando quindi di tracciamento, che non è propriamente uno strumento o una tecnologia, ma un atto, un comportamento, una componente importante di qualsiasi metodo efficace di lavoro.

In questo articolo affronteremo in tre sezioni quanto anticipato nel titolo:

  • Senso e scopo del tracciamento;
  • Cosa tracciare prima, dopo e durante il coding;
  • Come tracciarlo, con quali strumenti, con quali criteri e obiettivi in mente.

Ma, prima di cominciare, sincronizziamo qualche definizione utile:

Tracciamento: l'atto di lasciare una traccia ripercorribile del proprio processo produttivo.

Documentazione: la raccolta di tutto il materiale informativo utile a descrivere un progetto o un prodotto.

Versionamento: la pratica di differenziare diverse versioni (consecutive o alternative) di un progetto, e conseguentemente di un artefatto.

Senso e scopo del tracciamento

Chiunque converrà sul fatto che abbia sempre senso annotare in forma scritta quello che ci passa per la testa prima, durante e dopo lo svolgimento di un lavoro, se non altro per spirito storiografico. Ma certo, avere chiaro il motivo per cui lo stiamo facendo ci fornirà criteri utili su cosa esattamente lasciare scritto ai posteri, e su come annotarlo efficacemente.

Premettiamo che ogni atto di tracciamento si fa sperando che non serva mai: se tutto andrà bene, non sarà necessario tornare a riguardare "i verbali del processo". Dobbiamo quindi lasciare le nostre tracce nell'eventualità che qualcuno si ritrovi a seguirle, senza alcuna pretesa di prevedere se accadrà, quando accadrà e a chi accadrà. Spoiler: è molto difficile che tutto il materiale tracciato sia consultato, ma è estremamente probabile che buona parte di esso lo sia nel corso del tempo.
Quella che stiamo costruendo è una documentazione indiretta, di basso livello e di tipo additivoIndiretta perché emerge spontaneamente durante i lavori, di basso livello perché si focalizza sulle specifiche attività a cui fa riferimento, additiva perché non subisce mai modifiche, ma riporta strato su strato l'accumularsi nel tempo dei lavori sul progetto. Per questi motivi, tracciare non è documentare, ma generalmente le note di tracciamento più consultate contengono informazioni che dovrebbero finire nella documentazione del progetto.

Anche il versionamento contribuisce al tracciamento dei lavori: i messaggi di commit, se scritti bene, descrivono la storia delle modifiche apportate al codice, possono contenere avvisi riguardo a tali modifiche e soprattutto possono contenere rimandi a note di tracciamento più strutturate come le Issue su piattaforme come GitHub.

Ma qual è il vero purpose and meaning di questa noiosissima parte del lavoro di ogni sviluppatore?

Immagina che un collega abbia una domanda su un componente che hai programmato tu. Potresti fornirgli una risposta una tantum, e finita lì; oppure potresti tracciare la domanda e la risposta; oppure potresti già aver generato la risposta a quella domanda mentre lavoravi. In questo terzo caso, non c'è nessun bisogno che il tuo collega ti interrompa, perché da bravo professionista, prima di rompere le scatole ai colleghi, andrà a farsi un giro tra le issue del progetto e troverà tutto ciò che gli serve sapere. Quindi il tracciamento aiuta un team di sviluppo a ridurre il rumore causato da domande, interruzioni, confronti, riunioni, ecc.

Un altro caso frequente è che durante la vita del progetto si presentino due o più problematiche simili, che possono essere affrontate con lo stesso approccio. In questo caso farci un giro tra i nostri appunti ci farà risparmiare tempo e ci spingerà ad adottare soluzioni già collaudate. Il tracciamento costituisce una base per classificare problemi e soluzioni, garantendo la coerenza all'interno di un progetto.

In definitiva, il tracciamento è un'attività facilitatrice che non genera valore aggiunto di per sé, ma può costituire un importante leva nel governare l'accumulo di complessità, costruendo mappe dei diversi sentieri percorsi durante la vita del progetto.

Cosa tracciare

Partiamo da un presupposto tanto importante quanto semplice: l'insieme più ampio di quello che si può tracciare è tutto, quello più ristretto è niente.
Perché è una premessa importante? Perché, per ogni progetto e per ogni attività, è fondamentale capire qual è il livello di dettaglio che si vuole tracciare: non si può oggettivamente tracciare tutto, e non si dovrebbe mai fare un lavoro, per quanto semplice, senza lasciare alcuna traccia ai posteri.

Mettiamoci per un attimo nei panni di un maniaco totale del tracciamento, e cerchiamo di capire che cosa c'è dentro a questo tutto, andando dalle attività più macroscopiche verso quelle più micro.

Macro-obiettivi

In questa categoria mettiamo tutte le attività di raccolta degli obiettivi e dei requisiti. In pratica, il momento in cui il programmatore cerca di capire cosa deve fare in termini di risultato finale atteso.

Nota bene: non stiamo parlando di documentare la specifica, ma di tracciare le attività che ci porteranno ad averne una. Nel farlo, risponderemo a domande come:

  • Che materiale mi è stato fornito?
  • Dove trovo le informazioni?
  • A chi posso chiedere chiarimenti?
  • Quanto sono chiari i requisiti?
  • Quanto sono adeguate le mie competenze per soddisfare i requisiti?
  • Quale livello di complessità mi aspetto complessivamente da questo progetto?

Tracciare i macro-obiettivi significa ad esempio registrare una riunione in cui questi vengono spiegati, individuare cartelle condivise, canali di messaggistica in cui chiedere chiarimenti, ecc. Affronteremo meglio queste questioni più avanti, quando parleremo del Come tracciare.

È importante tracciare osservazioni, dubbi, perplessità. Si può essere portati a pensare che un'attività professionale di tracciamento dovrebbe verbalizzare solo dati oggettivi, come tempi, orari e vincoli; in realtà le nostre intuizioni sono preziosissime ancorché soggettive, poiché il nostro istinto professionale è forgiato dall'esperienza e può aiutarci ad anticipare problemi e ostacoli che potrebbero presentarsi durante la realizzazione del progetto.

Micro-obiettivi

Il miglior modo di governare la complessità è scomporla in parti. Sarà quindi fisiologico che, man mano che le nostre idee sul lavoro si chiariscono, andremo a definire degli obiettivi più di dettaglio. Nell'ambito del project management potrebbero a questo punto essere definite delle ondate (waves) o delle milestones, cioè dei traguardi intermedi con sotto-obiettivi specifici. A loro volta, questi traguardi intermedi raccoglieranno degli elementi di lavorazione, nella forma di taskuser storiesissues: obiettivi specifici che vanno a descrivere concretamente cosa ci sarà da fare.

Anche in questo caso, è utile andare a tracciare, magari direttamente sugli elementi di lavorazione, ponendosi domande come:

  • L'oggetto di lavorazione in questione è ben circoscritto?
  • Su quale area del progetto si andrà ad intervenire?
  • È chiaro chi dovrà lavorare a quest'attività?
  • Sarebbe utile allegare del materiale specifico?
  • Quando potrebbe essere complessa da per nulla a moltissimo?
  • Quali sono le altre attività che dipendono da questa, o da cui questa dipende?
  • Quanto tempo potrebbe impiegare?

Perché parliamo di queste cose in un'ottica di tracciamento e non di progettazione, pianificazione o documentazione? Perché, qualora la pianificazione dovesse subire delle variazioni (la legge di Murphy ci dice che le subirà), andremo a ricostruire una cronologia di tutte le variazioni subite dal progetto; in questo modo potremo analizzarne le cause oppure prendere decisioni future alla luce delle ragioni originali di quelle scelte che andremo a rivedere.

In questa fase, il senso del tracciamento consiste principalmente nel fare in modo che variazioni future non presentino conflitti o rotture rispetto a quanto originariamente pianificato; il tutto non tanto nell'ottica di evitare queste variazioni, ma di soddisfare le esigenze emergenti con cognizione di causa rispetto a quelle già assodate. Per questo è importante che il tracciamento sia puramente additivo, e cioè non presenti mai sostituzioni ma solo emendamenti in aggiunta alle cose già scritte.

Work in progress (WIP)

Prima o poi arriverà il momento in cui dovremo prendere in carico le nostre cose da fare (issue, task, stories, ecc) e metterci a lavorare. Magari non abbiamo affatto preso parte alla raccolta dei requisiti e alla pianificazione del progetto (eventualità generalmente non ottimale); in questo caso, la nostra attività di tracciamento inizia qui.

Prendiamo in carico una storia, apriamo il codice e iniziamo a programmare. Cosa tracciare a questo punto?

  • I preparativi, cioè le attività preliminari che consentono di iniziare a sviluppare. Se ad esempio abbiamo appena iniziato a lavorare ad un progetto già in essere, annoteremo le attività svolte per recuperare i sorgenti, per inizializzare i database, eccetera.
  • Il lavoro in sé: qui ci verranno incontro gli strumenti di versionamento, cioè nel 99% dei casi, Git.
  • Tutto ciò che emerge durante il lavoro: problemi, difficoltà, decisioni prese, deviazioni di percorso.
  • Le conclusioni: il lavoro è andato bene? male? è stato chiuso in tempo? è stato chiuso completamente?

Problemi o attività emergenti

Nessun piano sopravvive al contatto con la sua attuazione.
Proverbio militare

Nel preparare una battaglia i piani sono inutili, ma la pianificazione è fondamentale.
Eisenhower

Se la programmazione non fosse un processo creativo, esplorativo, emergente, sarebbe già stata automatizzata. Il fatto è che non esistono due software uguali, e ogni progetto presenta novità, imprevisti e prime volte. Per questi motivi, di tutte le istanze da tracciare, le questioni emergenti, cioè quelle che si presentano necessariamente in corso d'opera, sono probabilmente le più critiche. In questo caso, è utile annotare:

  • Le condizioni che hanno fatto emergere l'istanza;
  • L'entità dell'imprevisto o dei nuovi lavori da fare;
  • L'impatto che l'istanza emergente avrà o potrebbe avere sulle altre attività, sia quelle già svolte, sia quelle ancora da fare.

Su questo specifico tipo di tracciamento ci sarebbe un'importante raccomandazione da fare: nonostante la natura dirompente di questi elementi, bisogna sempre sforzarsi di limitare il rumore. La tentazione è quella di riempire di commenti il codice, di interrompere il lavoro degli altri, di chiedere consultazioni e confronti. Purtroppo però queste istanze emergono in corso d'opera proprio perché c'è un'opera in corso; bisogna cercare di essere chirurgici nel causare interruzioni ai propri colleghi; raccogliere da soli quante più informazioni possibili, scegliere i momenti e le sedi opportune per valutare le conseguenze di quanto emerso, se possibile proseguire il proprio lavoro su attività non impattate dall'imprevisto.

Informazioni mancanti

Questo potrebbe essere considerato un caso particolare dei problemi emergenti. Capita che in corso d'opera ci si renda conto di non avere a disposizione tutte le informazioni necessarie per completare un lavoro. Nella migliore delle ipotesi, una volta ottenute le informazioni mancanti, non ci saranno attività o altre questioni emergenti, e quindi l'imprevisto non presenterà alcuna conseguenza.

In questo caso l'operazione più spontanea è chiedere a chi quest'informazione potrebbe averla. Ma, visto che il nostro obiettivo è limitare il rumore, tracciando le nostre domande e soprattutto le risposte ricevute faremo in modo che, se una data domanda dovesse ripresentarsi (lo farà), la risposta sia immediatamente disponibile.

Debito tecnico

Inutile nascondersi dietro a un dito: le porcate si fanno ovunque. Le fanno tutti, anche i più professionali e perfezionisti. Non sempre le soluzioni adottate sono ottimali e qualche volta è già chiaro sin da subito che una soluzione raggiunta per compromesso presenterà delle controindicazioni o necessiterà di una bonifica in futuro. In gergo, tutte queste soluzioni non ottimali vengono definite debito tecnico, e riportano tutte le caratteristiche di un debito economico:

  • Facilitano il raggiungimento di soluzioni a breve termine (per questo il mondo ne è afflitto);
  • Presentano costi inizialmente bassi, ma prolungati nel tempo (interessi nel caso economico, controindicazioni o diminuzione della mantenibilità nel caso tecnico);
  • Se accumulati, divengono insostenibili.

Scontato dire che è importante avere sotto controllo la quantità di debito tecnico accumulata e smaltita nel corso di un progetto. In questo caso andremo a tracciare:

  • Il motivo per cui è stato "contratto" un debito tecnico;
  • In cosa consisterebbe la bonifica di tale debito;
  • Quali sono i rischi o i problemi causati dal debito, finché questo non verrà estinto.

Tempo

Questa è facile: il tempo-uomo, il cosiddetto effort, è semplicemente connesso ai costi di realizzazione di un determinato prodotto, oppure di una specifica attività. Quindi ha senso tracciarlo trasversalmente a tutti i livelli sopra elencati, e sarebbe opportuno tracciarne alcune varianti. Io personalmente con il mio team classifico il tempo in base a una serie di parametri:

  • Il tempo-uomo speso per un lavoro, non tenendo quindi conto della parallelizzazione del lavoro: la somma semplice del tempo speso su tutte le singole attività.
  • La durata effettiva in calendario, tenendo conto della parallelizzazione del lavoro, ma anche del fatto che non si passa mai l'intera settimana lavorativa a produrre, perché siamo esseri umani e per funzionare abbiamo bisogno di pause caffè, pause cazzeggio, distrazioni varie ed eventuali. Non solo: è alquanto improbabile che un team riesca a spendere il 100% del suo tempo produttivo settimanale sul progetto in questione; ci saranno riunioni, ci saranno altri progetti, ci sarà tutta una serie di attività contestuali che sarebbe ingenuo ignorare.

In ogni caso è utile distinguere il tempo stimato, da tracciare prima del lavoro, da quello speso, da annotare a lavoro ultimato. Questo è chiaramente utile per motivi economici, ma anche per affinare nel tempo la nostra capacità di stimare il lavoro.

Complessità/Difficoltà

La difficoltà di un lavoro è evidentemente un parametro soggettivo e a mala pena quantificabile numericamente. Infatti, non è il caso di fare troppe elucubrazioni su questo parametro, anch'esso trasversale a tutti i livelli e a tutte le fasi del progetto.

La difficoltà può essere valutata su due piani:

  • qualitativo: "questo lavoro è facilissimo soprattutto per Tizio che l'ha già fatto mille volte"
  • quantitativo (ma pur sempre soggettivo): "questo lavoro si quota 8 in una scala dove 1 è un Hello World e 10 è il Kernel Linux"

Consiglio: non usare mai un Hello World e il Kernel Linux come estremi di scala per una valutazione quantitativa. Scegli sempre punti di un ordine di complessità compatibile con quello del progetto o dell'attività in questione.

Per semplificare, può essere pratico nel concreto unire le due valutazioni, riducendole ad una semplice scala simile a banale/facile/impegnativo/infernale ed associando ad ognuna di queste valutazioni un numero. Una pratica suggerita da molti è quella di non utilizzare una scala numerica lineare (es. 1, 2, 3, ecc) ma una che cresca in modo progressivamente sempre più verticale (es. la serie di Fibonacci); in questo modo si rappresenta numericamente il calo di accuratezza nel valutare oggetti di complessità crescente.

Generalmente è buona pratica individuare una soglia di complessità che si ritiene governabile; se un elemento di lavorazione supera tale soglia, questo andrebbe preso come un segnale di applicare il dividere et impera, cioè di scomporre tale istanza in sottoelementi più semplici.

Come tracciarlo

Bene, abbiamo definito un paniere di cose da tracciare; ma come farlo bene nel concreto?

Quali sono gli strumenti più adatti a tracciare le diverse attività?
Quali sono i formati più efficaci?
Qual è la soglia giusta di dettaglio e di zelo da applicare?

Ti bastan poche briciole...

Con questo titolo, mettiamo insieme due classici: Pollicino e Il libro della giungla. Da un lato, abbiamo l'esigenza di mitigare il rischio di dover ripercorrere il lavoro svolto, le decisioni prese, i problemi riscontrati; dall'altro, dobbiamo fare i conti con l'economia e con la realtà. Il principio del barely sufficient viene in nostro aiuto:

Per ogni casistica, bisogna dosare lo zelo organizzativo a una misura che sia strettamente sufficiente a soddisfarne lo scopo.

In altre parole, la fatica spesa su un'attività facilitatrice dev'essere necessariamente rapportata all'entità del lavoro che si vuole facilitare; nello specifico, a quanto sarà difficile orientarsi in quel lavoro in assenza di una traccia.

Gli strumenti giusti

Ovviamente, per ogni tipo di attività, ci sono gli strumenti giusti. Ma anche adottare i supporti e i formati giusti può fare la differenza.

Riunioni e confronti verbali possono essere registrate/i.
Non serve che ogni persona presente prenda appunti; piattaforme di collaborazione come Microsoft Teams o Zoom offrono la trascrizione delle riunioni; in aggiunta può essere utile, durante una riunione, annotarsi i minutaggi in cui vengono fornite informazioni importanti o discusse questioni cruciali.

Le chat sono una forma implicita di tracciamento.
Rendersene conto significa approfittarne appieno: quasi tutte le app di messaggistica consentono di segnare come importanti alcuni messaggi e hanno funzioni di ricerca; questo significa che se accompagniamo le informazioni importanti con le giuste parole chiave, sarà più facile per noi e per gli altri recuperare quelle informazioni.

I sistemi di versioning:
una delle cose più utili in Git sono i messaggi di commit, che vanno usati bene. Il messaggio di commit deve presentare una prima riga estremamente sintetica; nella maggior parte dei casi è sufficiente usare un verbo (aggiunto/rimosso/implementato/modificato/risolto) e un complemento oggetto (configurazione database/vista carrello/validazione form contatto/baco doppio salvataggio). Le righe successive possono contenere qualche nota aggiuntiva, come ad esempio il fatto che una certa modifica apportata richieda una gestione particolare, oppure che sia correlata ad una certa issue. Esistono molte convenzioni alternative su come scrivere i messaggi di commit; l'importante come sempre è concordarne una e poi rispettarla.

Le piattaforme costruite attorno ai sistemi di versioning:
BitBucket, GitLab, GitHub, ecc. Tutte queste piattaforme offrono strumenti per gestire su più livelli la pianificazione e il tracciamento del lavoro. In GitLab possiamo definire MilestoneIterazioniIssueIncident; in GitHub abbiamo ProgettiCardIssue. Tutte queste piattaforme supportano l'uso del Markdown, un formato di testo molto semplice da imparare e da scrivere, che viene automaticamente convertito ad HTML e mostrato come un testo formattato una volta salvato.

Carta e penna sopravvivono a tutto.
Nel mio caso quest'affermazione è impropria, poiché da quando ho comprato il ReMarkable (un tablet con schermo e-ink) ho effettivamente abbandonato il mio quadernetto cartaceo. Sta di fatto che un qualche supporto su cui si possa scarabocchiare, tirare frecce, fare bozzetti, resta utilissimo. Chiaramente si tratta di un tipo di supporto e di formato non molto adatto alla collaborazione, sebbene non ci sia niente di cui vergognarsi nell'allegare ad una Issue su GitHub un bozzetto fatto a mano (purché sia presentabile e chiaramente leggibile).

I commenti nel codice dovrebbero costituire una forma sempre temporanea di tracciamento
e quasi mai di documentazione, ad eccezione di quelli esplicitamente utilizzati come intestazione, per documentare all'esterno moduli, classi e funzioni.
I più intransigenti sostengono che ogni commento in una codebase costituisca un debito tecnico. Sebbene gli argomenti a sfavore dei commenti siano piuttosto convincenti, non dobbiamo mai perdere il senso pratico. Molti ambienti di sviluppo hanno funzionalità di ricerca di commenti che iniziano con TODO o NOTE, e dato che mentre programmiamo abbiamo il codice davanti, annotare qualcosa sullo stesso codice è sicuramente qualcosa di molto immediato. Come regola generale raccomanderei di considerare temporanei tutti i commenti. In tal senso, è legittimo considerarli un debito.

I file README dovrebbero essere usati come documentazione,
ma possono essere considerati strumenti di tracciamento in senso lato. Se ad esempio un README contiene una sezione Obiettivo della settimana, che viene aggiornata di settimana in settimana, grazie a git potremo sempre ricostruire lo storico di tutti gli obiettivi delle passate settimane. Certo, sarebbe meglio tracciare gli obiettivi settimanali con delle Milestone o delle Issue dedicate.

Conclusioni

Nella filosofia si parla spesso di tempo lineare versus tempo ciclico; nell'ambito di un progetto software, il tempo è più simile a un labirinto. Poche attività sono veramente lineari e molte diramazioni si rivelano essere vicoli ciechi, ma vanno comunque esplorate man mano che si costruisce un quadro di comprensione complessivo. Lasciare briciole dietro di sé è un modo poco costoso per ridurre progressivamente il costo necessario per orientarsi e governare la complessità.

In tal senso, il tracciamento è una forma di credito tecnico.

Impara a programmare in 3 mesi con il Corso di Coding Hackademy su Laravel PHP

Diventa Sviluppatore web in 3 mesi

Scopri il coding bootcamp Hackademy

Programma Completo