JavaRush /Java Blog /Random-IT /Pausa caffè #103. In difesa del “Clean Code”: 100 consigl...

Pausa caffè #103. In difesa del “Clean Code”: 100 consigli intramontabili

Pubblicato nel gruppo Random-IT
Fonte: Hackernoon “Clean Code” di Robert C. Martin è il libro di programmazione più consigliato di tutti i tempi. Cerca libri utilizzando la query "migliori libri per sviluppatori software" e avrai quasi la certezza di trovare questo libro nei risultati di ricerca. E mentre alcune persone ritengono che non valga la pena prestare attenzione al Clean Code, direi che tali sentimenti sono profondamente sbagliati. Sì, alcuni dei consigli contenuti nel libro sono discutibili. Sì, alcuni contenuti sembrano obsoleti. Sì, alcuni esempi creano confusione. E' tutto vero. Ma non sminuiamo così frettolosamente i tanti consigli utili offerti da questo libro! Ignorare completamente Clean Code semplicemente a causa di alcune cattive idee non è la soluzione migliore. Pausa caffè #103.  In difesa del “Clean Code”: 100 eterni consigli - 1Quindi, senza ulteriori indugi, diamo un'occhiata ai migliori consigli che Clean Code ha da offrire! Esamineremo ogni capitolo, riassumendo le idee offerte dallo zio Bob e dai suoi coautori.

Capitolo 1: Codice pulito

  1. La quantità complessiva di disordine aumenta nel tempo.

  2. Ripristinare da zero un sistema obsoleto è molto difficile. Il refactoring e i miglioramenti incrementali saranno l’opzione migliore per questo.

  3. In una codebase disordinata, le attività che dovrebbero richiedere solo poche ore possono richiedere giorni o settimane per essere completate.

  4. Prenditi il ​​tempo per agire rapidamente.

  5. Il codice pulito fa bene una cosa. Il codice errato tenta di fare troppo.

  6. Il codice pulito è ben testato.

  7. Quando si legge un codice ben scritto, ogni funzione fa più o meno quello che ti aspetteresti.

  8. Se non sei d’accordo con un principio insegnato da qualcuno con anni di esperienza, dovresti almeno considerare il suo punto di vista prima di ignorarlo.

  9. Il codice viene letto molto più spesso di quanto non venga scritto.

  10. Il codice più facile da leggere è più facile da modificare.

  11. Lascia la base di codice migliore di quando l'hai trovata (regola dei Boy Scout).

Capitolo 2: Il significato dei nomi

  1. Scegli attentamente i nomi delle variabili.

  2. Scegliere dei buoni nomi è difficile.

  3. Il nome di una variabile o di una funzione dovrebbe indicare di cosa si tratta e come viene utilizzata.

  4. Evitare di utilizzare nomi di variabili a carattere singolo, ad eccezione dei nomi di uso comune, come i per una variabile contatore in un ciclo.

  5. Evitare l'uso di abbreviazioni nei nomi delle variabili.

  6. I nomi delle variabili dovrebbero essere pronunciabili in modo da poterne parlare e pronunciarli ad alta voce.

  7. Utilizza nomi di variabili facili da trovare.

  8. Le classi e gli oggetti devono avere nomi sotto forma di sostantivi.

  9. I nomi dei metodi e delle funzioni devono essere verbi o coppie verbo-sostantivo.

Capitolo 3: Funzioni

  1. Le funzioni dovrebbero essere piccole.

  2. La funzione deve eseguire un'azione.

  3. Le funzioni devono avere nomi descrittivi.

  4. Estrai il codice nel corpo if/else o trasforma le istruzioni in funzioni dal nome chiaro.

  5. Limita il numero di argomenti accettati da una funzione.

  6. Se una funzione richiede molti argomenti di configurazione, valuta la possibilità di combinarli in un'unica variabile dei parametri di configurazione.

  7. Le funzioni devono essere pure, il che significa che non hanno effetti collaterali e non modificano gli argomenti di input.

  8. La funzione deve essere un comando o una query, ma non entrambi contemporaneamente (Separazione delle query dei comandi).

  9. È meglio rimuovere errori ed eccezioni dal codice piuttosto che lasciare errori nel codice.

  10. Estrai il codice duplicato in funzioni dal nome chiaro (non ripeterti).

  11. I test unitari semplificano il refactoring.

Capitolo 4: Commenti

  1. I commenti potrebbero essere errati. Potrebbero essere sbagliati all'inizio oppure potrebbero essere inizialmente accurati e poi diventare obsoleti nel tempo man mano che il codice cambia.

  2. Utilizza i commenti per descrivere il motivo per cui è scritto così com'è, invece di spiegare cosa sta succedendo.

  3. I commenti possono spesso essere evitati utilizzando variabili con nomi chiari ed estraendo sezioni di codice in funzioni con nomi chiari.

  4. Prefissa i commenti TODO con prefissi coerenti per renderli più facili da trovare. Rivedi e ripulisci periodicamente i tuoi commenti TODO.

  5. Non utilizzare Javadoc solo per il gusto di usarli. I commenti che descrivono cosa fa un metodo, quali argomenti accetta e cosa restituisce sono ridondanti nella migliore delle ipotesi e fuorvianti nella peggiore.

  6. I commenti dovrebbero includere tutte le informazioni rilevanti e il contesto di cui il lettore avrà bisogno. Non essere pigro quando scrivi un commento.

  7. I commenti sui log e i commenti sugli autori dei file non sono necessari a causa del controllo della versione e della colpa di Git.

  8. Non commentare il codice morto. Basta cancellarlo. Se pensi che avrai bisogno del codice in futuro, ecco a cosa serve il controllo della versione.

Capitolo 5: Formattazione

  1. Come team, seleziona una serie di regole per la formattazione del codice, quindi applica tali regole in modo coerente. Non importa con quali regole sei d'accordo, devi raggiungere un accordo.

  2. Utilizza la formattazione automatica del codice e un analizzatore di codice. Non fare affidamento sulle persone per trovare e correggere manualmente ogni errore di formattazione. Ciò è inefficiente, improduttivo e una perdita di tempo durante la revisione del codice.

  3. Aggiungi spazi verticali tra le righe di codice per separare visivamente i blocchi di codice correlati. Tutto ciò che serve è creare una nuova linea tra i gruppi.

  4. I file di piccole dimensioni sono più facili da leggere, comprendere e spostare rispetto ai file di grandi dimensioni.

  5. Le variabili dovrebbero essere dichiarate vicino a dove vengono utilizzate. Per le funzioni di piccole dimensioni, solitamente si trova nella parte superiore della funzione.

  6. Anche per funzioni brevi o istruzioni if, formattatele comunque correttamente invece di scriverle su una riga.

Capitolo 6: Oggetti e strutture dati

  1. I dettagli di implementazione in un oggetto devono essere nascosti dietro l'interfaccia dell'oggetto. Fornendo un'interfaccia utilizzabile dai consumatori di un oggetto, si semplifica il successivo refactoring dei dettagli di implementazione senza causare modifiche sostanziali. Le astrazioni semplificano il refactoring.

  2. Qualsiasi dato pezzo di codice non dovrebbe avere alcuna conoscenza delle parti interne dell'oggetto su cui opera.

  3. Quando lavori con un oggetto, dovresti richiedergli di eseguire un comando o una query, piuttosto che chiedergli informazioni sui suoi interni.

Capitolo 7: Correzione degli errori

  1. La gestione degli errori non dovrebbe interferire con il resto del codice nel modulo.

  2. È meglio rimuovere errori ed eccezioni dal codice piuttosto che lasciare errori nel codice.

  3. Scrivi test con errori per assicurarti che il tuo codice li identifichi e non li perda.

  4. I messaggi di errore dovrebbero essere informativi, con tutto il contesto necessario per risolvere il problema in modo efficace.

  5. Avvolgere le API di terze parti in un sottile strato di astrazione semplifica la sostituzione futura di una libreria con un'altra.

  6. Avvolgere le API di terze parti in un sottile strato di astrazione rende più semplice simulare la libreria durante i test.

  7. Utilizzare il modello Special Case o il modello Null Object per gestire comportamenti eccezionali, ad esempio quando determinati dati non esistono.

Capitolo 8: Confini

  1. Le librerie di terze parti aiutano ad accelerare la consegna dei prodotti consentendoti di esternalizzare varie attività.

  2. Scrivi dei test per assicurarti di utilizzare correttamente la libreria di terze parti.

  3. Utilizza il modello dell'adattatore per colmare il divario tra l'API di una libreria di terze parti e l'API che vorresti avere.

  4. Avvolgere le API di terze parti in un sottile strato di astrazione semplifica la sostituzione futura di una libreria con un'altra. (Ripetere dal capitolo 7)

  5. Avvolgere le API di terze parti in un sottile strato di astrazione rende più semplice simulare la libreria durante i test. (Ripetere dal capitolo 7)

  6. Cerca di non fornire alla tua applicazione troppe informazioni sui dettagli di qualsiasi libreria di terze parti.

  7. È meglio dipendere da ciò che controlli piuttosto che da ciò che non controlli.

Capitolo 9: Test unitari

  1. Il codice di test dovrebbe essere pulito quanto il codice di produzione (con alcune eccezioni, solitamente legate alla memoria o all'efficienza).

  2. Man mano che il codice di produzione cambia, cambia anche il codice di test.

  3. I test aiutano a mantenere il codice di produzione flessibile e gestibile.

  4. I test ti consentono di apportare modifiche, permettendoti di effettuare il refactoring con sicurezza senza il timore di non notarlo tu stesso.

  5. Struttura i tuoi test utilizzando il modello Arrange-Act-Assert (noto anche come Build-Operate-Check, Setup-Exercise-Verify o Given-When-Then).

  6. Utilizza funzioni specifiche del dominio per semplificare la scrittura e la lettura dei test.

  7. Assegna un punteggio a un concetto per test.

  8. I test devono essere veloci.

  9. I test devono essere indipendenti.

  10. I test devono essere ripetibili.

  11. I test non dovrebbero richiedere conferma.

  12. I test dovrebbero essere scritti in modo tempestivo, poco prima o dopo la scrittura del codice di produzione, non mesi dopo.

  13. Se i tuoi test sono pessimi, aspettati che ci siano bug nel tuo codice.

Capitolo 10: Classi

  1. Le classi dovrebbero essere piccole.

  2. Le classi dovrebbero essere responsabili solo di una cosa e dovrebbero avere una sola ragione per cambiare (principio di responsabilità unica).

  3. Se non riesci a trovare un nome chiaro per la classe, probabilmente è troppo grande.

  4. Il tuo lavoro non finisce quando riesci a far funzionare un pezzo di codice. Il prossimo passo sarà il refactoring e la pulizia del codice.

  5. L'utilizzo di molte classi piccole anziché di numerose classi di grandi dimensioni nell'applicazione riduce la quantità di informazioni che uno sviluppatore deve comprendere quando lavora su una determinata attività.

  6. Avere una buona suite di test ti consente di eseguire il refactoring con sicurezza quando dividi classi di grandi dimensioni in classi più piccole.

  7. Le classi dovrebbero essere aperte all'estensione, ma chiuse alle modifiche (principio aperto-chiuso).

  8. Interfacce e classi astratte creano collegamenti che semplificano i test.

Capitolo 11: Sistemi

  1. Utilizza l'inserimento delle dipendenze per offrire agli sviluppatori la flessibilità di passare qualsiasi oggetto con l'interfaccia appropriata a un'altra classe.

  2. Utilizza l'inserimento delle dipendenze per creare interfacce tra gli oggetti nella tua applicazione per semplificare i test.

  3. I sistemi software non sono come un edificio che deve essere progettato in anticipo. Sono più simili a città che crescono e si espandono nel tempo, adattandosi alle esigenze attuali.

  4. Rimandare la decisione fino all'ultimo momento critico.

  5. Utilizza un linguaggio specifico del dominio in modo che gli esperti e gli sviluppatori del dominio utilizzino la stessa terminologia.

  6. Non complicare eccessivamente il tuo sistema. Usa la cosa più semplice che funzioni.

Capitolo 12: Distribuzione

  1. I sistemi che non possono essere testati non possono essere verificati e i sistemi che non possono essere verificati non dovrebbero mai essere implementati.

  2. La scrittura dei test porta a una progettazione migliore perché il codice facile da testare spesso utilizza l'inserimento di dipendenze, le interfacce e l'astrazione.

  3. Una buona serie di test eliminerà la paura di danneggiare l'applicazione durante il refactoring.

  4. La duplicazione del codice crea maggiori rischi perché ci sono più punti nel codice che possono essere modificati e ancora più punti in cui è possibile nascondere gli errori.

  5. Il codice che scrivi ora è più facile da capire perché sei profondamente coinvolto nella sua comprensione. Non è facile per gli altri raggiungere rapidamente lo stesso livello di comprensione.

  6. La maggior parte del costo di un progetto software è legato alla manutenzione a lungo termine.

  7. I test servono come documentazione vivente di come la tua applicazione dovrebbe (e si comporta).

  8. Non andare oltre una volta che il codice funziona. Prendetevi il tempo per renderlo più chiaro e comprensibile.

  9. Molto probabilmente la prossima persona che leggerà il tuo codice nel prossimo futuro sarai tu. Sii gentile con te stesso nel futuro scrivendo un codice facile da capire.

  10. Resisti al dogma. Abbraccia il pragmatismo.

  11. Ci vogliono decenni per diventare un ingegnere del software davvero bravo. Puoi accelerare la tua curva di apprendimento imparando dagli esperti intorno a te e imparando i modelli di progettazione comunemente utilizzati.

Capitolo 13: Parallelismo

  1. Scrivere codice parallelo è difficile.

  2. Bug e problemi occasionali difficili da riprodurre sono spesso problemi di concorrenza.

  3. Il test non garantisce che la tua applicazione sarà priva di bug, ma ridurrà al minimo il rischio.

  4. Scopri i problemi comuni di concorrenza e le relative possibili soluzioni.

Capitolo 14: Perfezionamento sequenziale

  1. Il codice pulito di solito non inizia con una tabula rasa. Prima scrivi una soluzione approssimativa e poi la rifattorizzi per renderla più pulita.

  2. È un errore smettere di lavorare sul codice una volta che ha iniziato a funzionare. Prenditi il ​​tempo per renderlo ancora migliore dopo che ha già funzionato.

  3. I disordini crescono gradualmente.

  4. Se ti trovi in ​​una situazione in cui l'aggiunta di funzionalità è troppo difficile o richiede troppo tempo, smetti di scrivere funzionalità e inizia il refactoring.

  5. Un cambiamento incrementale è spesso migliore che ricostruire da zero.

  6. Utilizza il Test-Driven Development (TDD) per apportare grandi quantità di modifiche molto piccole.

  7. Una buona progettazione del software implica separare gli aspetti del codice e separare il codice in moduli, classi e file più piccoli.

  8. È più facile sistemare un pasticcio subito dopo averlo fatto piuttosto che farlo dopo.

Capitolo 15: Elementi interni di JUnit

  1. I nomi delle variabili negative o le espressioni condizionali sono un po' più difficili da comprendere rispetto a quelli positivi.

  2. Il refactoring è un processo iterativo pieno di tentativi ed errori.

  3. Lascia la base di codice migliore di quando l'hai trovata (regola dei Boy Scout). (Ripetuto dal capitolo 1)

Capitolo 16: Refactoring di SerialDate

  1. Le revisioni del codice e le critiche al nostro codice ci rendono migliori e dovremmo accoglierlo con favore.

  2. Prima fai funzionare il codice, poi correggilo.

  3. Non tutte le righe di codice necessitano di test.

Capitolo 17: Odori ed euristiche

  1. Il codice pulito non è un insieme di regole, ma piuttosto un sistema di valori che determinano la qualità del tuo lavoro.

[In questo capitolo, lo zio Bob elenca altre 66 varianti del suo codice e della sua euristica, molte delle quali sono state trattate nel resto del libro. Riprodurli qui significherebbe essenzialmente copiare e incollare il nome di ciascun elemento, quindi mi sono astenuto dal farlo. Ti suggerirei invece di leggere il libro!]

Conclusione

Terminiamo da dove abbiamo iniziato: Clean Code di Robert C. Martin è il libro di programmazione più consigliato di tutti i tempi. C'è una buona ragione per questo.
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION