La buona cucina richiede tempo. Se vi facciamo aspettare è per servirvi meglio e per accontentarvi.
– Menu del Restaurant Antoine, New Orleans
I progetti software che sono finiti male per mancanza di tempo sono più numerosi di quelli falliti per tutte le altre cause messe insieme
Prima di tutto, le nostre tecniche di stima sono scarsamente sviluppate. Detto più seriamente, rispecchiano un presupposto non dichiarato che è del tutto falso, cioè che tutto andrà bene.
In secondo luogo, le nostre tecniche di stima confondono erroneamente lo sforzo con i passi avanti, nascondendo l’assunto che esseri umani e mesi siano intercambiabili.
In terzo luogo, poiché siamo incerti nelle nostre stime, i manager nel mondo del software spesso non hanno la cortese insistenza dello chef del Restaurant Antoine.
In quarto luogo, l’andamento rispetto al calendario previsto viene monitorato malamente. Tecniche che sono consolidate e di routine in altre discipline ingegneristiche sono considerate innovazioni radicali nell’ingegneria del software.
In quinto luogo, quando ci si rende conto che i tempi stanno scivolando in avanti, la risposta naturale (e tradizionale) è aggiungere forza lavoro. Come cercare di spegnere un incendio con la benzina, questo non fa che peggiorare, e di gran lunga, le cose. Più fuoco richiede più benzina e così inizia un ciclo rigenerativo che finisce per portare al disastro.
Ottimismo
Tutti i programmatori sono ottimisti. Forse questa moderna pratica magica attrae le persone che credono nel lieto fine e nelle fate madrine. Forse le centinaia di frustrazioni pratiche allontanano tutte le persone, tranne quelle che si concentrano d’abitudine sull’obiettivo finale. Forse è semplicemente che i computer sono giovani, i programmatori sono ancora più giovani, e i giovani sono sempre ottimisti. Comunque funzioni il processo di selezione, il risultato è indiscutibile: Questa volta funzionerà di sicuro, oppure Ho appena trovato l’ultimo bug.
Perciò, il primo assunto falso alla base dei calendari per la programmazione di sistema è che tutto andrà bene, ovvero che ogni attività richiederà solo il tempo che deve occupare.
Nel caso di una singola attività, l’assunto che tutto andrà bene ha un effetto probabilistico sul calendario. In effetti può andare tutto come pianificato, perché esiste una distribuzione di probabilità per il ritardo che si incontrerà e anche il caso nessun ritardo ha una probabilità finita. Un grande lavoro di programmazione, però, è costituito da molte attività, alcune delle quali dipendenti fra loro. La probabilità che tutte vadano bene diventa molto piccola, tendente a zero.
Il mese-uomo
Il secondo modo fallace di pensare si esprime nella stessa unità di misura utilizzata per le stime e la pianificazione: il mese-uomo. Il costo indubbiamente varia con il prodotto del numero degli esseri umani e del numero dei mesi, ma l’andamento del lavoro no. Quindi il mese-uomo come unità per misurare le dimensioni di un lavoro è un mito pericoloso e fuorviante. Implica che esseri umani e mesi siano intercambiabili.
Leggi anche: Clean Code: l’importanza del codice agile e pulito
Uomini e mesi sono beni intercambiabili solo quando un’attività può essere suddivisa fra molte persone senza bisogno di alcuna comunicazione fra loro. Questo è vero se si devono raccogliere grano o cotone; non è nemmeno approssimativamente vero per la programmazione di sistemi.
Se un’attività non può essere partizionata a causa di vincoli di sequenza, l’applicazione di un maggior numero di persone non ha alcun effetto sul calendario. La gestazione di un nuovo essere umano richiede nove mesi, non importa quante donne vengano assegnate al compito. Molte attività relative al software hanno questa caratteristica, per la natura sequenziale del debug.
Nel caso di attività che possono essere partizionate, ma che richiedono comunicazione fra le sottoattività, bisogna aggiungere alla quantità di lavoro da svolgere anche l’impegno della comunicazione. Perciò il meglio che si può fare è un po’ peggio di un equo compromesso fra esseri umani e mesi.
Il carico aggiuntivo della comunicazione è costituito da due parti, formazione e intercomunicazione. Ogni persona che lavora deve essere formata e imparare a conoscere la tecnologia, gli obiettivi dell’iniziativa, la strategia generale e il piano di lavoro. Questa formazione non può essere partizionata, perciò questa parte dell’impegno aggiuntivo varia linearmente con il numero delle persone che lavorano.
L’intercomunicazione è peggio. Se ogni parte dell’attività deve essere coordinata separatamente con ogni altra parte, l’impegno aumenta come n(n – 1)/2. Per tre persone è richiesta una quantità di intercomunicazione a coppie tripla rispetto a due sole persone; per quattro persone è sei volte quella necessaria per due. Se, inoltre, devono esserci incontri fra tre, quattro o più persone per risolvere congiuntamente le cose, la faccenda peggiora ulteriormente. Lo sforzo aggiuntivo della comunicazione può controbilanciare completamente la divisione dell’attività originale e ci porta alla situazione rappresentata nella figura che segue.
Poiché la costruzione del software è intrinsecamente un’attività di sistemi (un esercizio di interrelazioni complesse), l’impegno di comunicazione è grande e rapidamente domina la riduzione del tempo necessario per le singole attività resa possibile dal partizionamento. Aggiungere altre persone quindi allunga i tempi, non li accorcia.
Test di sistemi
Non vi sono parti del calendario su cui i vincoli sequenziali incidano tanto estesamente come sul debug dei componenti e sul testing del sistema. Inoltre, il tempo richiesto dipende dal numero e dalla sottigliezza degli errori incontrati. Teoricamente il loro numero dovrebbe essere zero. A causa del nostro ottimismo, di solito ci aspettiamo che il numero dei bug sia più piccolo di quello che si rivela poi essere. Perciò quella del testing di solito è la parte della programmazione che viene calendarizzata nel modo meno adeguato.
Da qualche anno uso con successo questa regola empirica per pianificare una attività relativa al software:
- 1/3 pianificazione;
- 1/6 codifica;
- 1/4 test dei componenti e test precoce del sistema;
- 1/4 test del sistema, in presenza di tutti i componenti.
Questa soluzione è diversa dalla calendarizzazione convenzionale, per molti aspetti importanti.
- La parte dedicata alla pianificazione è maggiore del normale. Anche così, è a malapena sufficiente per produrre una specifica dettagliata e robusta, ma è insufficiente per tener conto della ricerca o dell’esplorazione di tecniche totalmente nuove.
- La metà del tempo dedicata al debug del codice completo è molto maggiore di quella normalmente prevista.
- Alla parte che è facile stimare, cioè la scrittura del codice, viene assegnato solo un sesto del tempo complessivo.
Nell’esaminare progetti calendarizzati in modo convenzionale, ho visto che ben pochi prevedevano metà del tempo totale per il testing, ma nella maggior parte dei casi finivano per dedicare metà del tempo effettivo a quello scopo. Molti di quei progetti erano in linea con i tempi previsti finché non arrivavano alla fase del testing del sistema.
Il non tenere conto di un tempo sufficiente per il testing di sistema è particolarmente disastroso. Dato che il ritardo arriva alla fine dell’intervallo di tempo previsto, nessuno si rende conto dei problemi fino a che la data di consegna non è ormai vicina. Le cattive notizie, date all’ultimo minuto e senza preavviso, sono irritanti, per i clienti come per i manager.
Il ritardo a questo punto, inoltre, ha ripercussioni finanziarie, e anche psicologiche, molto gravi. Il progetto ha uno staff completo e il costo giornaliero è massimo. Più seriamente, il software deve sostenere altre attività di business (la consegna di computer, l’esercizio di nuovi impianti e così via) e i costi secondari del ritardo indotto in queste altre attività sono molto alti, perché ormai è quasi il momento della consegna del software. In effetti, questi costi secondari possono di gran lunga superare tutti gli altri. Perciò è molto importante prevedere nel calendario originale un tempo adeguato per il testing del sistema.
Stime senza spina dorsale
Osservate che per il programmatore, come per lo chef, l’urgenza del cliente può governare il completamento programmato dell’attività, ma non può governare il completamento reale. Una omelette, promessa in due minuti, può sembrare proceda bene. Se però entro i due minuti non è pronta, il cliente ha due scelte: aspettare o mangiarla cruda. I clienti del software hanno le stesse scelte.
Il cuoco ha una scelta ulteriore: può alzare la fiamma. Il risultato spesso è una omelette che non si può più salvare: bruciata da una parte, cruda dall’altra.
Non penso che i manager del software abbiano intrinsecamente meno coraggio e fermezza degli chef, né di altri manager di progetti tecnici. Una pianificazione sbagliata per adeguarsi alla data desiderata dal cliente però è molto più comune nella nostra disciplina che in ogni altro ambito dell’ingegneria. È molto difficile difendere vigorosamente, plausibilmente e rischiando il proprio lavoro, una stima che non è derivata da alcun metodo quantitativo, è sostenuta da pochi dati e certificata principalmente dalle sensazioni dei manager.
Finché non avremo una base più solida per le stime, i singoli manager dovranno irrigidire la spina dorsale e difendere le loro stime, con la garanzia che le loro semplici intuizioni sono meglio di stime derivate solo dal desiderio.
Disastro rigenerativo di pianificazione
Che cosa si fa quando un progetto software essenziale è in ritardo? Si aggiunge manodopera, naturalmente. Come abbiamo visto, questo può essere di aiuto, o magari no.
Supponiamo che ci sia un’attività che si stima richieda 12 mesi-uomo e a cui sono assegnate tre persone per quattro mesi; supponiamo anche che esistano traguardi intermedi misurabili A, B, C, D, che in base al calendario dovrebbero essere raggiunti alla fine dei diversi mesi.
Ora supponiamo che il primo traguardo intermedio non venga raggiunto finché non sono trascorsi due mesi. Quali sono le alternative che ha il manager?
- Dare per scontato che l’attività debba essere conclusa nel tempo previsto. Assumere che solo la prima parte dell’attività sia stata stimata male, e che quindi la prossima figura precedente racconti correttamente la situazione. Quindi restano 9 mesi-uomo di lavoro e due soli mesi, perciò saranno necessarie 4,5 persone. Aggiunge 2 persone alle 3 già assegnate.
- Dare per scontato che l’attività debba essere conclusa nel tempo previsto. Assumere che tutta la stima fosse uniformemente bassa, cosicché la situazione sia descritta effettivamente dalla seconda figura qui sotto. Allora restano 18 mesi-uomo di lavoro e due soli mesi di tempo, perciò saranno necessarie 9 persone. Aggiunge 6 persone alle 3 assegnate.
- Ripianificare, prevedendo un tempo sufficiente perché il lavoro possa essere svolto con cura e fino in fondo, senza che ci sia bisogno di nuovo di una ripianificazione.
- Tagliare parte dell’attività. Nella pratica questo tende a succedere comunque, una volta che il team osserva uno scivolamento dei tempi. Quando i costi secondari del ritardo sono molto elevati, questa è l’unica azione che si può intraprendere. Le uniche alternative del manager sono ridurre l’attività formalmente e attentamente, ripianificare o stare a guardare mentre l’attività viene ridotta senza dichiararlo a causa di una progettazione frettolosa e di test incompleti.
Nei primi due casi, insistere che l’attività venga completata senza modifiche in quattro mesi è disastroso. Consideriamo gli effetti rigenerativi, per esempio, della prima alternativa. Le due nuove persone introdotte, per quanto competenti e per quanto rapidamente reclutate, avranno bisogno di una formazione da parte di una delle persone esperte. Se questa richiede un mese, 3 mesi-uomo saranno dedicati a un lavoro non previsto nella stima originale. Inoltre l’attività, inizialmente suddivisa in tre parti, ora deve essere ripartizionata in cinque; quindi un po’ del lavoro già fatto andrà perso e il testing del sistema si allungherà. Così, alla fine del terzo mese, restano sostanzialmente più di 7 mesi-uomo di lavoro, ma sono disponibili 5 persone formate e un solo mese di tempo. Il prodotto è in ritardo esattamente come se non fosse stata introdotta alcuna nuova persona.
Per sperare di farcela in quattro mesi, considerando solo il tempo per la formazione e non il ripartizionamento e i test aggiuntivi per il sistema, bisognerebbe aggiungere 4 persone, non 2, alla fine del secondo mese. Per tenere conto anche degli effetti del ripartizionamento e dei test di sistema, bisognerebbe aggiungere ancora altre persone. Ora, però, c’è un team formato da almeno 7 persone, non 3, quindi aspetti come l’organizzazione del team e la divisione dei compiti sono differenti non solo per grado ma anche per natura.
Notiamo che alla fine del terzo mese la situazione appare molto nera. Il traguardo dell’1 marzo non è stato raggiunto, nonostante tutti gli sforzi manageriali. È molto forte la tentazione di ripetere il ciclo, aggiungendo ancora più manodopera. In questo sta la follia.
Tutto quello che precede vale nell’ipotesi che solo il primo traguardo fosse stato stimato erroneamente. Se l’1 marzo si fa l’ipotesi prudenziale che tutto il programma fosse ottimistico, verrebbe da aggiungere 6 persone solo all’attività originale. Il calcolo degli effetti dovuti a formazione, ripartizionamento e test di sistema è lasciato come esercizio al lettore. Senza dubbio, il disastro rigenerativo condurrà più avanti a un prodotto più scarso di quel che non sarebbe successo ridefinendo il calendario con le tre persone di partenza, senza aggiungerne altre.
La legge di Brooks
Semplificando enormemente, possiamo allora formulare la Legge di Brooks:
L’aggiunta di manodopera a un progetto software in ritardo lo fa ritardare ancora di più.
Questa dunque è la demitizzazione del mese-uomo. Il numero dei mesi necessari per un progetto dipende dai suoi vincoli sequenziali. Il numero massimo di persone dipende dal numero delle sottoattività indipendenti. Da questi due valori si possono trarre calendari che prevedono meno persone e più mesi. (L’unico rischio è l’obsolescenza del prodotto.) Non si possono però ottenere calendari attendibili utilizzando più persone e meno mesi. Il numero dei progetti software andati storti per mancanza di tempo previsto per la realizzazione è maggiore del numero dei progetti falliti per tutte le altre cause combinate.
Questo articolo richiama contenuti da Il mito delle giornate-uomo.
Immagine di apertura di Alex Kotliarskyi su Unsplash.