Debito tecnico: possibili conseguenze di uno sviluppo software economico
Un team di sviluppatori che lavora in modo rapido ed economico sullo sviluppo di un software o l’installazione di un’infrastruttura informatica ottiene questo risparmio tramite l’assunzione di un debito tecnico. Debito tecnico è il termine usato per designare le conseguenze di negligenza intenzionale o non intenzionale, errori e carenze nel codice, poiché correzioni e manutenzioni rallentano la produttività e comportano costosi lavori aggiuntivi. A cosa occorre prestare attenzione se si vuole evitare un debito tecnico nello sviluppo del software?
Perché si chiama debito tecnico?
Nel 1992, Ward Cunningham, programmatore e coautore del Manifesto per lo sviluppo agile di software, introdusse la metafora del debito tecnico. Con questa immagine Cunningham ha voluto chiarire quanto sia importante per il software il refactoring, ovvero la correzione regolare del codice. Questo è l’unico modo per evitare che il software diventi sempre più indebitato a causa di crescenti carenze funzionali e debolezze strutturali.
Il termine debito implica anche un interesse, di conseguenza il debito tecnico è per le aziende un’importante componente da considerare dal punto di vista finanziario. Il debito tecnico non solo comporta maggiori sforzi e riduce la produttività a causa della conseguente manutenzione, ma genera anche maggiori costi. Più un team leader trascura la manutenzione di un’infrastruttura o di un’applicazione IT difettosa, maggiore è l’interesse che il debito genera e più costose sono le correzioni del codice.
Il debito tecnico si riferisce a errori intenzionali o accidentali, a carenze e debolezze nel codice, che derivano da una mancanza di comunicazione, scarsa gestione del team, mancanza di qualifiche o dalla pubblicazione frettolosa di prodotti. Questo debito è destinato a crescere continuamente fino a quando non viene eseguito il refactoring.
Il quadrante del debito tecnico: quattro tipi di debito
Secondo Ward Cunningham il debito tecnico deriva dalla negligenza nella programmazione del codice, che, a causa di vincoli di tempo o di budget, porta a una risoluzione dei problemi più rapida, ma errata. Un codice accurato e completo è complesso e lungo. Di conseguenza, gli sviluppatori possono scegliere di utilizzare un codice sporco, per risparmiare tempo e fatica. Questi risparmi sono però ottenuti attraverso il debito.
Per Cunningham questo aspetto economico della programmazione non è insolito o innaturale. Ma se il debito tecnico non viene compensato dal refactoring e il codice non viene regolarmente ottimizzato, lo sviluppo si interrompe o si ferma a causa dei tassi di interesse.
Martin Fowler, autore di “Refactoring: Improving the Design of Existing Code”, ha concretizzato la metafora di Cunningham e ha suddiviso il debito tecnico in quattro tipi, illustrati nel quadrante del debito tecnico qui riportato:
Debito imprudente | Debito prudente | |
Debito volontario |
|
|
Debito involontario |
|
|
Il debito tecnico secondo Cunningham e Fowler può quindi sorgere sia consapevolmente che inavvertitamente. Poiché la tecnologia e la programmazione sono soggette a continue revisioni e miglioramenti, è difficile evitare il code smell e il code erosion. Inoltre, il software invecchia e, in mancanza di aggiornamenti e refactoring, accumula debito. Nella maggior parte dei casi il debito tecnico può essere spiegato con scelte economiche o errori di programmazione intenzionali o non intenzionali.
Quali sono le cause del debito tecnico?
Il debito tecnico di solito ha effetti simili sullo sviluppo del software, ma le sue cause possono variare notevolmente.
- Mancanza di gestione della qualità: i progetti vengono eseguiti senza meccanismi di controllo, misurazione e test di garanzia della qualità e accumulano debiti di continuo.
- Pressione economica: i fattori economici e lo sviluppo rapido del software sono prioritizzati su richiesta dei clienti o a causa della competitività, e viene trascurato un codice pulito.
- Mancanza di qualifiche: le conoscenze tecniche del team di sviluppo non soddisfano i requisiti di un codice elegante e pulito. Il risultato è un code smell o uno spaghetti code.
- Documentazione / comunicazione insufficiente: il processo di sviluppo viene eseguito senza documentazione parallela delle estensioni e delle modifiche del codice. Inoltre, le modifiche al codice non vengono registrate e comunicate ai programmatori successivi. Le possibilità di refactoring sono limitate o non disponibili.
- Refactoring differito: il debito tecnico deliberatamente accettato non viene prontamente risolto perché il refactoring viene trascurato o rinviato.
- Sviluppo di applicazioni parallele: fasi di sviluppo parallele riunite e non coordinate portano all’accumulo di debito.
- Codice troppo complesso: le sezioni del codice sono troppo complicate e illogiche. Piccoli cambiamenti possono portare a ulteriori errori e aumentare il debito. Nel peggiore dei casi anche qui viene generato lo spaghetti code.
- Processi di sviluppo non strutturati: lo sviluppo dell’applicazione inizia prima che un progetto o dei processi specifici siano stati definiti e decisi.
- Codice di outsourcing: le fasi di sviluppo sono esternalizzate e comportano errori nel codice quando le sezioni vengono successivamente unite; errori che la direzione del team accetta o trascura.
- Cambiamenti a breve termine nel processo: i cambiamenti a breve termine nel codice non vengono testati a causa dei tempi ristretti.
Debito tecnico e sviluppo agile del software
Ward Cunningham non solo ha definito la metafora del debito tecnico ma è anche coautore e primo firmatario del Manifesto per lo sviluppo agile di software. Questa filosofia nello sviluppo del software mira a promuovere lo sviluppo e la pubblicazione di applicazioni più produttive e flessibili.
Invece di essere legati a progetti di grandi dimensioni per lunghi periodi di tempo, i team diventano più piccoli e indipendenti e dovrebbero mirare a ottenere fasi di lavoro più brevi e release più rapide per progetti minori quali applicazioni, parti di programma e aggiornamenti.
Lo sviluppo agile del software comporta che i team possano scrivere e modificare il codice in piccoli passaggi rendendo quindi possibile che le fasi di lavoro vengano completate più rapidamente. Infatti, concentrarsi su velocità e produttività aumenta il rischio di accumulare un codice sporco e quindi un debito tecnico. Soprattutto quando lo sviluppo agile del software è eseguito senza un corrispondente refactoring continuo, il debito inevitabilmente cresce.
Quali effetti ha il debito tecnico sullo sviluppo del software?
Gli effetti del debito tecnico corrispondono, a grandi linee, alle conseguenze dei prestiti finanziari. Se il debito non viene ripagato regolarmente e puntualmente, maturano interessi, che si manifestano in un rallentamento dello sviluppo, in un calo della produttività e in un aumento dei costi.
È pertanto nell’interesse dei clienti eseguire una gestione e un monitoraggio della qualità estesi e a lungo termine dopo lo sviluppo del software, al fine di evitare che una rapida ed economica realizzazione e produzione dei prodotti risulti in delle correzioni di errori costose o in un arresto nello sviluppo.
Come evitare il debito tecnico?
Il debito tecnico non può essere completamente escluso a causa delle nuove tecnologie e del cambiamento degli approcci nello sviluppo del software. Inoltre, nella maggior parte dei casi, il debito tecnico viene addirittura accettato al fine di pubblicare programmi e applicazioni in modo rapido e regolare. Tuttavia, esistono misure preventive per evitare o ridurre l’emergere o la crescita del debito:
- Introdurre processi standardizzati per il refactoring e la gestione della qualità
- Utilizzare strumenti costantemente aggiornati per la misurazione e l’analisi degli errori
- Promuovere una conoscenza tecnica attraverso una formazione continua, che tenga il passo con gli sviluppi informatici oltre a determinare la composizione del team in base alle qualifiche
- Organizzare ordinatamente un codice con l'uso di suddivisioni in classi e metodi chiari, e scriverlo in modo comprensibile per programmatori nuovi o esterni
- Definire chiare responsabilità e funzioni all'interno dei team per evitare duplicati, ridondanze e fasi di lavoro controproducenti
- Mantenere aggiornata l‘architettura informatica attraverso il monitoraggio costante, la misurazione e la garanzia della qualità