Luca Corradi
Luca Corradi

Co-Founder

Clean Code

Conoscere un linguaggio di programmazione non significa saper sviluppare software efficaci.
Sviluppare un software che funziona non significa averlo fatto in modo efficiente.
Aver fatto un software efficiente non significa averlo scritto in modo comprensibile e mantenibile.

Clean code: un’arte

Scrivere “codice pulito” è un’arte vera e propria che condensa tanti aspetti e buone pratiche per la corretta stesura di codice efficace, efficiente, leggibile e mantenibile ed è stata ampiamente professata dal celebre C. Martin Clean Code: A Handbook of Agile Software Craftsmanship

Di seguito sono messi in luce alcuni dei punti tratti dal libro, adattati alla mia visione della programmazione.

1. Funzionalità

La base fondamentale di un software che si rispetti è, ovviamente, la necessità che sia efficace in conformità con i requisiti di analisi.
Tuttavia, ciò che contraddistingue un prodotto sviluppato da mani esperte è la sua efficienza.

L’efficienza nel software è risolvere un problema ottimizzando le metriche più rilevanti, principalmente: <>tempo di esecuzione, quantità di memoria utilizzata.
Ogni funzione di un software si può misurare, secondo la teoria della complessità, con la notazione “Big-O” (O grande) che esprime quanto variano le metriche (numero di istruzioni necessarie e memoria consumata) con l’aumentare la dimensione del problema. Tanto più la curva di crescita della sua complessità rimane “bassa” tanto più è considerata efficiente.

Spesso, però, per ricorrere a miglioramenti di performance è necessario esprimere i calcoli sfruttando proprietà matematiche che comportano la scrittura di un codice criptico e di difficile comprensione. Laddove il perfezionamento delle performance non è business critical, introdurre un codice inutilmente comprensibile (e quindi difficilmente mantenibile nel tempo) potrebbe non essere la scelta più indicata

Nella realtà dei fatti è infatti sempre opportuno considerare quale sia la stima della dimensione reale del problema.

Ad esempio, Se dovessimo avere due funzioni che producono lo stesso risultato, di cui:

  1. la prima diventa gradualmente sempre più efficiente della seconda quando la dimensione del problema supera un valore ipotetico “100”, ma è molto complicata da comprendere nei suoi passaggi
  2. la seconda ha un’efficienza equiparabile alla prima per una dimensione del problema fino a “90”, ma è piuttosto comprensibile alla lettura

Avendo constatato da analisi che la dimensione media del problema nei casi reali è di “80” sarebbe decisamente preferibile optare per la seconda, poiché il divario di efficienza nei casi reali è equiparabile. La comprensione generale del codice scritto fornito dalla seconda funzione tuttavia agevolerebbe gli interventi di futuri manutentori.

2. Leggibilità

Un aspetto molto controverso e trascurato nel mondo della programmazione, specialmente nei giovani sviluppatori ancora inesperti, è l’attenzione alla leggibilità del codice. Favorire la leggibilità vuol dire adottare una linea comune nella scrittura di tutti i file che mantenga i giusti spazi tra i diversi blocchi di istruzioni e rispetti una nomenclatura stabilita.
Un altro fattore che determina la leggibilità è la comprensibilità di quanto scritto. Una funzione scritta con una sintassi molto concisa, quasi esoterica, può risultare poco intuitiva. Quando è necessario applicare modifiche può diventare un ostacolo molto insidioso comprendere esattamente il comportamento di un blocco di codice contorto, aumentando le possibilità di introdurre nuovi bug.

Il codice deve essere chiaro, esplicativo, e deve essere la prima fonte di documentazione nel funzionamento. Leggendo un clean code si può seguire il filo logico dei flussi, comprendere il funzionamento dai nomi delle funzioni senza dover leggerne ed interpretare il contenuto.

Le funzioni di alto livello devono comunicare in modo semplice tutto il flusso principale da rappresentare, richiamando al loro interno macro funzioni che definiscono macro operazioni. Ogni funzione specifica si serve di ulteriori funzioni sempre più dettagliate fino ad arrivare alle specifiche più sottili.

Naturalmente la soluzione ottimale sta nel mezzo tra i due estremi ma, anche se la leggibilità è quasi sempre una priorità, in certi casi dove l’efficienza deve avere massima importanza può essere giustificabile favorire la stesura di codice altamente performante e di difficile lettura. In questi casi è importante comunque racchiudere questo blocco con una accurata descrizione che ne documenti il funzionamento.

3. Mantenibilità

In qualsiasi progetto strutturato c’è l’esigenza di portarne avanti lo sviluppo nel corso degli anni, implementando funzionalità evolutive e correggendo problemi che si possono verificare.
Con il passare del tempo i team di sviluppo cambiano, anche totalmente, e nuove risorse vengono incaricate ad intervenire su codici scritti tempo prima, da altre persone.
Trovarsi davanti un codice chiaro, strutturato, documentato, comprensibile agevola notevolmente il lavoro di qualsiasi nuovo professionista che spesso non si trova nessuna documentazione allegata, oppure questa differisce dall’attuale implementazione.

In virtù di questo, scrivere codice pulito significa anche impostare il flusso e i nomi delle funzioni in modo che possano essere “parlanti” e leggibili come se fosse un articolo di giornale: da cima a fondo, rispettando l’ordine logico e temporale nel quale le varie funzioni vengono richiamate.
Il blocco principale deve poter comunicare l’intero flusso ad un livello panoramico, mentre tutte le funzioni annidate definiscono il dettaglio dei passaggi.

Commenti

Servirsi di commenti per descrivere un funzionamento è un escamotage instabile per evitare il “dovere” di scrivere codice pulito.

Nel tempo i commenti diventano la fonte più grande di incomprensione.

Inizialmente si parte con le più buone intenzioni di commentare qualsiasi blocco rispecchiando esattamente quello che è il funzionamento, ma con il passare del tempo diventa un aspetto trascurato, specialmente se il progetto passa sotto altre mani.
Inoltre, lasciare nel tempo blocchi di codice commentati non fa che aumentare l’incomprensione: spesso diventa obsoleto, ma chi si ritrova a leggerlo inevitabilmente si chiede se ci fosse un motivo giustificato per la sua presenza, alimentando dubbi sul funzionamento.
Il risultato è che ci si ritrova ad avere un codice che fa una cosa, mentre i commenti ne descrivono un’altra.

Ecco perché i commenti andrebbero usati in modo centellinato, solo nei punti dove è impossibile spiegarsi meglio con la struttura del codice, come ad esempio:

  • Spiegare i possibili valori e condizioni di campi nello strato di integrazione con sistemi esterni
  • Commentare il comportamento di una funzione criptica che è stata scelta per i suoi notevoli benefici in termini di performance

Conclusioni

Essendo più un’arte che una scienza, la dottrina del “clean code” si presta a confronti ed interpretazioni, ma indubbiamente i suoi princìpi sono un ottimo faro da seguire per chi aspira a diventare un professionista che rivolge estrema attenzione alla qualità.

  • Software
  • Coding

Condividi l'articolo

Leggi altri articoli

Il mondo IT è sofisticato, lo sappiamo.

Bisogno di aiuto?

Scrivici per una consulenza gratuita.