Scroll Top
Via Antonio Amato, 20/22 84131 Salerno (SA)

Introduzione al Clean Code – Parte 1

clean code

(articolo redatto da Gaetano De Pascale)

Il Clean Code è un concetto fondamentale nella programmazione moderna, in quanto promuove la scrittura di codice leggibile, manutenibile e facilmente comprensibile da altri sviluppatori.

È bene specificare che quando parliamo di Clean Code non vogliamo definire un rigido insieme di regole, bensì una serie di principi che ci aiutano a scrivere un codice intuitivo, comprensibile e facile da modificare.

In questo articolo esploreremo le migliori pratiche per scrivere codice pulito e vedremo come l’adozione di nomi descrittivi, una corretta organizzazione del codice, la riduzione del codice duplicato, l’uso di funzioni pure e una gestione adeguata degli errori possono migliorare la qualità e la leggibilità del codice.

Nel tempo il Clean Code può trasformare la tua esperienza di sviluppo e consentirti di creare software più robusto e di successo.

Una Guida in tre step

Questo è il primo di una serie di tre articoli in cui introdurremo i principi che sono alla base del clean code.

La nostra guida introduttiva sarà così strutturata:

  1. In questo primo articolo parleremo di quali sono le best practice e le norme da seguire per attribuire dei buoni nomi a variabili, funzioni e classi.
  2. Nel secondo appuntamento vi daremo indicazioni su come organizzare il codice, faremo poi una panoramica di quelli che sono i principi alla base della filosofia ( SOLID – DRY – KISS – YAGNI), concludendo con la gestione degli errori.
  3. Infine nella terza parte, dopo aver parlato dell’importanza dei test e di quelli che sono gli strumenti a supporto da utilizzare, trarremo le conclusioni finali del nostro viaggio.

Seguimi!

LE ORIGINI DEL CLEAN CODE

Possiamo attribuire la paternità di questa “arte” a Robert Cecil Martin, che nel libro “Clean Code: A Handbook of Agile Software Craftsmanship” lo ha utilizzato come termine per definire il buon codice. Martin, conosciuto anche come Uncle Bob, è tra le altre cose anche uno dei firmatari del manifesto Agile e ideatore dei principi SOLID.

L’autore quando introduce il Clean Code dice: “Any fool can write code that a computer can understand. Good programmers write code that humans can understand”.

Infatti, un codice pulito riduce la complessità, facilita la manutenzione e la correzione degli errori, permette una migliore collaborazione tra gli sviluppatori, migliora la qualità del software e ne favorisce le future evoluzioni.

Nomi descrittivi e consistenti

Uno dei principali aspetti del Clean Code è l’uso di nomi descrittivi e consistenti per le variabili, le funzioni e le classi. Un buon nome deve essere chiaro, conciso e facilmente comprensibile. Inoltre, i nomi delle variabili dovrebbero essere sostantivi scelti in modo da evitare ambiguità e confusione, mentre per le funzioni dovremmo sempre usare verbi che ne spieghino il comportamento.
Es. “numeroUtenti” è una variabile, mentre “contaUtenti()” sarà una funzione.

Può sembrare un suggerimento banale, ma proviamo a fare mente locale o cercare nei nostri progetti, quante volte troviamo variabili chiamate “x”, “i”, “index”, “item”, “temp”, “ex”? Certo nella maggior parte dei casi si capirà, in maniera più o meno immediata, il significato dal contesto.

Prendiamo questo esempio:

// Bad Code
function check(value) {
    let validi, i, s, set1, set2, setp, setd;
    if (value === '') return false;
    if (value.length !== 16) return false;
    validi = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    value = value.toUpperCase();
    for (i = 0; i < 16; i++) {
        if (validi.indexOf(value.charAt(i)) == -1) return false;
    }
    set1 = &quot;0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ&quot;;
    set2 = &quot;ABCDEFGHIJABCDEFGHIJKLMNOPQRSTUVWXYZ&quot;;
    setp = &quot;ABCDEFGHIJKLMNOPQRSTUVWXYZ&quot;;
    setd = &quot;BAKPLCQDREVOSFTGUHMINJWZYX&quot;;
    s = 0;
    for (i = 1; i <= 13; i += 2) s += setp.indexOf(set2.charAt(set1.indexOf(value.charAt(i))));
    for (i = 0; i <= 14; i += 2)  s += setd.indexOf(set2.charAt(set1.indexOf(value.charAt(i))));
    if (s % 26 !== value.charCodeAt(15) - 'A'.charCodeAt(0)) return false;
    return true;
}

Prima di risolvere un eventuale bug, o fare un’evoluzione, quanto tempo impiegheresti a capire a cosa serve questa funzione ed il significato di ogni variabile?

E se invece l’autore avesse scritto la funzione in questo modo?

// Better Code
function isItalianFiscalCodeValid(code) {
    const VALID_CHARS = &quot;ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789&quot;;
    const VALID_ODD_CHAR_SET = &quot;0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ&quot;;
    const VALID_EVEN_CHAR_SET = &quot;ABCDEFGHIJABCDEFGHIJKLMNOPQRSTUVWXYZ&quot;;
    const CONTROL_CHAR_SET = &quot;BAKPLCQDREVOSFTGUHMINJWZYX&quot;;
    if (!code || code.length !== 16) {
        return false;
    }
    code = code.toUpperCase();
    for (let i = 0; i < 16; i++) {
        if (VALID_CHARS.indexOf(code.charAt(i)) === -1) {
            return false;
        }
    }
    let oddSum = 0;
    let evenSum = 0;
    for (let i = 1; i <= 13; i += 2) {
        const oddCharIndex = VALID_ODD_CHAR_SET.indexOf(code.charAt(i));
        const evenCharIndex = VALID_EVEN_CHAR_SET.indexOf(code.charAt(i - 1));
        oddSum += CONTROL_CHAR_SET.charAt(oddCharIndex).charCodeAt(0) - 'A'.charCodeAt(0);
        evenSum += CONTROL_CHAR_SET.charAt(evenCharIndex).charCodeAt(0) - 'A'.charCodeAt(0);
    }
    const controlChar = (oddSum + evenSum) % 26;
    return controlChar === code.charCodeAt(15) - 'A'.charCodeAt(0);
}

Cambia totalmente la prospettiva vero?

Prendersi il tempo necessario per la scelta di nomi appropriati è un investimento prezioso per garantire la leggibilità e la manutenibilità del codice nel lungo termine.

Funzioni

Le funzioni svolgono un ruolo fondamentale nella scrittura di codice pulito e mantenibile. Una buona pratica per migliorare la leggibilità e la comprensibilità del codice è attribuire nomi significativi alle funzioni. I nomi delle funzioni dovrebbero essere descrittivi e riflettere chiaramente ciò che fa o l’obiettivo che essa cerca di raggiungere. Evitare nomi generici come ‘doStuff()’ o ‘check()’, che non danno alcuna indicazione sul loro scopo.

Inoltre, è importante strutturare le funzioni in modo che siano concise e svolgano un’unica responsabilità.

LE FUNZIONI DEVONO FARE UNA COSA SOLA. DEVONO FARLA BENE. NON DEVONO FARE ALTRO.

Questo principio, noto come principio di singola responsabilità, aiuta a rendere le funzioni più facili da comprendere, testare e manutenere. Se una funzione sta facendo troppe cose diverse, può diventare difficile seguirne il flusso di esecuzione e correggere eventuali errori.

Una regola pratica per mantenere le funzioni concise è limitare la loro lunghezza. Idealmente, una funzione dovrebbe essere di dimensioni ridotte, sarebbe preferibile che siano meno di 20 linee di codice, ma già fare in modo che rientrino sempre nello schermo e non si debba scrollare per visualizzarla tutta è un buon inizio. Se una funzione inizia a diventare troppo lunga, può essere un segnale che sta facendo troppe operazioni. In questo caso, è consigliabile suddividerla in funzioni più piccole e ben definite, ciascuna responsabile di una parte specifica del compito complessivo.

Inoltre, se ad esempio abbiamo una funzione per leggere le informazioni di un utente “getUser()“, dovremmo evitare di utilizzare un’altra funzione chiamata “takeUserInfo()” per reperire le informazioni relative allo stesso utente. Se decidiamo di dare il prefisso ‘get’ per le funzioni che prelevano dati dal DB usiamo sempre quello! Mantenere uno standard facilita la comprensione del codice e rende più semplice la ricerca di elementi correlati. Inoltre, l’utilizzo di nomi descrittivi e coerenti aiuta anche i futuri sviluppatori che lavoreranno sul codice a capire più facilmente le intenzioni e la logica del codice.

Infine, è consigliabile utilizzare commenti in modo conciso e mirato per spiegare il comportamento o la logica complessa all’interno di una funzione. Tuttavia, l’obiettivo dovrebbe essere quello di scrivere codice che sia autoesplicativo il più possibile, riducendo al minimo la necessità di commenti per comprendere il funzionamento delle funzioni. Ricordiamo sempre che i commenti andrebbero evoluti insieme al codice; quindi, commentiamo il codice solo se strettamente necessario.

clean code

In conclusione, le funzioni ben strutturate e nominate in modo appropriato sono fondamentali per un codice pulito.

Adottare una nomenclatura descrittiva e assicurarsi che le funzioni siano concise, focalizzate su una singola responsabilità e ben commentate contribuisce a rendere il codice più leggibile, manutenibile e facilmente comprensibile per gli sviluppatori che dovranno interagire con esso.

Conclusioni

In questo primo articolo abbiamo introdotto la filosofia del Clean Code e l’importanza di scrivere codice che sia pulito, leggibile e manutenibile. Abbiamo esplorato l’importanza di attribuire nomi descrittivi e consistenti alle variabili, alle funzioni e alle classi, nomi che aiutano a comunicare in modo chiaro l’intento e la funzione del codice.

Inoltre, abbiamo approfondito il concetto di funzioni ben strutturate, che dovrebbero essere concise, focalizzate su una singola responsabilità e facilmente comprensibili. Le funzioni ben nominate e organizzate contribuiscono a rendere il codice più facile da leggere, testare e manutenere.

Nei prossimi articoli, continueremo a esplorare altre importanti pratiche del Clean Code. Discuteremo dell’importanza della struttura e dell’organizzazione del codice, delle principali filosofie come SOLID, DRY, YAGNI e KISS, della gestione degli errori, dei test, delle pratiche e degli strumenti aggiuntivi per migliorare ulteriormente la qualità del nostro codice.

Seguendo i principi del Clean Code, potremo sviluppare software di alta qualità, che sia facile da comprendere, estendere e manutenere nel tempo. Ricordiamo che la scrittura del codice è solo una parte del processo di sviluppo del software, ma adottare le buone pratiche del Clean Code ci aiuterà a costruire un fondamento solido per il nostro lavoro.


Se anche tu vuoi occuparti di importanti progetti di  sviluppo software
dai un’occhiata alle nostre opportunità di lavoro e conosciamoci subito!

Questo sito utilizza cookies propri e si riserva di utilizzare anche cookie di terze parti per garantire la funzionalità del sito e per tenere conto delle scelte di navigazione.
Per maggiori dettagli e sapere come negare il consenso a tutti o ad alcuni cookie è possibile consultare la Cookie Policy.

USO DEI COOKIE

Se abiliti i cookie nella tabella sottostante, ci autorizzi a memorizzare i tuoi comportamenti di utilizzo sul nostro sito web. Questo ci consente di migliorare il nostro sito web e di personalizzare le pubblicità. Se non abiliti i cookie, noi utilizzeremo solo cookies di sessione per migliorare la facilità di utilizzo.

Cookie tecnicinon richiedono il consenso, perciò vengono installati automaticamente a seguito dell’accesso al Sito.

Cookie di statisticaVengono utilizzati da terze parti, anche in forma disaggregata, per la gestione di statistiche

Cookie di social networkVengono utilizzati per la condivisione di contenuti sui social network.

Cookie di profilazione pubblicitariaVengono utilizzati per erogare pubblicità basata sugli interessi manifestati attraverso la navigazione in internet.

AltriCookie di terze parti da altri servizi di terze parti che non sono cookie di statistica, social media o pubblicitari.