Sei sulla pagina 1di 6

🤠

Clean Code Notes


Nomi significativi
Nomi classi → Senza Verbo.
Nomi metodo → Frasi verbali.
Una parola un concetto. (ovvero non riutilizzare una parola per diversi scopi).
Utilizza un termine per rappresentare un determinato concetto ed utilizza sempre
quella.

Usate nomi tratti dal dominio della soluzione.

Quando non è possibile utilizzare la nomenclatura tratta dal dominio del


problema (Design pattern).

Funzioni
Le funzioni devono essere piccole e che facciano una cosa sola, ovvero un solo
livello di astrazione per funzione.

Per funzioni con istruzioni switch cercare di utilizzare un AbstractFactory.


Le funzioni di possono categorizzare in funzioni:

Monadiche (un solo parametro)

Diadiche (due parametri)

Triadi (tre parametri)

Ci sono casi dove è utile accorpare degli argomenti all'interno di una classe per poi
passarli a funzioni che li utilizzano (DTO).

I nomi delle funzioni possono contenere parole su cosa fanno e come utilizzarle
ovvero l'ordine degli argomenti.

Il nome di una funzione deve indicare ciò che fa, altrimenti si potrebbe
nascondere un effetto collaterale.

Se la vostra funzione deve modificare lo stato di qualcosa, lo deve fare per l'oggetto
a cui appartiene tale modifica. (poiché solo l'oggetto stesso si conosce, l'esterno non

Clean Code Notes 1


deve conoscere dettagli di esso).
"Separate i comandi dalle richieste"

La vostra funzione dovrebbe modificare lo stato oppure restituire qualche


informazione, su tale oggetto.

Dove possibile usare le eccezioni invece di restituire codici di errore, con i codici il
chiamante deve gestire il caso, in più estraete i blocchi try/catch.

Commenti
I commenti vanno usati per spiegare qualcosa che può sembrare illogico.

Formattazione & Ordinamento


La formattazione verticale: Aprendo un file si parte dal conoscere i suoi dettagli di
altissimo livello per poi proseguire fino al livello più basso su cui opera.

Per il resto affidarsi agli standard PSR-1 e PSR-2.

Oggetti e strutture
Una classe non si limita a gestire i suoi attributi con semplici getter e setter. Deve
esporre delle interfacce astratte per la manipolazione dei suoi attributi senza far
conoscere all'esterno l'implementazione.
Oggetti: Attributi manipolati tramite interfacce astratte.

Strutture: Attributi direttamente manipolati.

Il codice procedurale (che impiega strutture) facilità l'aggiunta di nuove funzioni


senza modificare l'assetto esistente. Il codice OO, al contrario, facilità l'aggiunta di
nuove classi senza modificare funzioni esistenti.

Il codice procedurale complica l'aggiunta di nuove strutture, perché tutte le funzioni


devono cambiare. Il codice OO complica l'aggiunta di nuove funzioni, perché tutte le
classi devono cambiare (metti caso aggiungi una funzione ad una interfaccia che
viene implementata da diverse classi → tipo se hai applicato l'OCP Open closed
principle).

TRADE OFF TRADE OFF TRADE OFF!!!! ZIO PORCO!!

Legge di Demetra
Un metodo f di una classe C dovrebbe richiamare solo i metodi di:

Clean Code Notes 2


C;

un oggetto creato da f;

un oggetto passato come argomento a f;

un oggetto contenuto in una variabile di istanza di C;

Data transfer Object (DTO)


DTO tipo di strutture per trasferimenti a diversi componenti nel sistema utilizzato di
default. (gli attributi dovrebbero essere public come si vede dal libro, ma è una
opinione).

Active Record (poco visto)


Traduzioni dirette della tabelle di un DB o altre fonti di dati.

Non bisogna inserire dei metodi di manipolazione altrimenti si crea un ibrido tra
oggetto e struttura. E quando si ha un ibrido, prendiamo tutti i "contro" di entrambi le
parti che formano l'ibrido realizzato.

Gestione degli errori


Bisogna cercare di lanciare eccezioni al posto di codici di return poiché quest'ultimi
obbligano al chiamante, l'immediata gestione dei codici di errore andando così a
sporcare il normale flusso che descrive ciò che accade. E utile scrivere il blocco try-
catch-finally e scrivere dei test che forzino queste eccezioni per poi scrivere i veri
test per il restante della funzionalità implementata. Questo aiuterà a tenere separato
il livello di visibilità del normale flusso dalla gestione delle eccezioni.

Valutare se utilizzare solo eccezioni controllate poichè quest'ultime introducono un


costo sulla manutenzione di tali eccezioni. Infatti, se lanciate un'eccezione
controllata da un metodo del vostro codice e la "catch" si trova tre livelli sopra,
dovete dichiarare tale eccezione nella signature di ogni metodo su ogni livello. In
certi, casi è utile generalizzare una classe di eccezioni se ognuna di queste porta
allo stesso comportamento. Quindi è possibile wrappare tali eccezioni in una classe
e lanciare una unica eccezione che rappresenti tali eccezioni. Alcune eccezioni
possono essere evitate tramite l'uso dello Special Case Pattern si tratta di una
classe o una configurazione di un oggetto che gestisca un caso speciale di solito è
tratto dalle regole di business.

Meglio non restituire null!

Clean Code Notes 3


Se siete tentati di far restituire null a un metodo, piuttosto lanciate un'eccezione o
restituite un oggetto Special Case (tipo se devi tornare un array con degli elementi e
non trovi gli elementi torni un array vuoto.).

Delimitazioni
Utilizzando funzionalità esterne al nostro applicativo (package, bundle) è utile
focalizzarsi a tenere un unico punto di unione tra questi in modo tale che quando il
codice esterno cambierà noi avremo la possibilità di intervenire su un singolo punto
del nostro sistema. Quando utilizziamo codice esterno vogliamo assicurarci un
single point of failure!
Inoltre possiamo creare dei test per le chiamate ad API esterne il che ci permette di
verificare se una versione nuova di API o package è funzionale per i nostri scopi,
altrimenti se così non fosse possiamo assicurarci di capire su quali parti del codice
possiamo intervenire.

Unit test (TDD) Test Driven Development


Non scrivere codice di produzione finché non avrai scritto uno unit test di stress.

Non procederai nello unit test più di quanto sia sufficiente per ottenere un
fallimento e la mancata compilazione è un fallimento.

Non scriverai più codice di produzione di quello che è sufficiente a passare


l'attuale test di stress.

Bisogna avere cura dei test, i test garantiscono maggiore flessibilità sulla modifica
della struttura e architettura per avere un progetto pulito.
Test: chiarezza, semplicità ed espressività.

I test vengono strutturati come segue.


Costruisci, Utilizza e Controlla il risultato.
Il test deve controllare 1 sola cosa. "Given-When-Then".

Classi
Organizzare le classi in oridne di costanti, viarabili, statiche pubbliche, poi variabiliti
statiche private seguite dalle variabili private di istanza. Sono rare poi le variabili
pubbliche.
Funzioni public poi funzioni private, alternate in base all'utilizzo delle prime.

Clean Code Notes 4


L'incapsulazione non bisogna allentarla per ottenere test più facili!

Single responsabiliti principle


Un classe o modulo dovrebbe avere un solo motivo per cambiare.

Coesione
Se i metodi di una classe coinvolgono molteplici variabili di istanza di quella classe,
allora la classe ha molta coesione, al contrario si dovrebbe valutare di separare tale
classe per generare classi più coese.

Inoltre possiamo organizzare gli interventi di modifica sfuttando il principio OCP


Open-Close Principle: Le classi dovrebbero essere aperte alle estensioni ma chiuse
alle modifiche.
Isolamento dalle modifiche

Soddisfare le dipendenze delle classi tramite interfacce!


In questo modo possiamo passare qualsiasi oggetto che implementi tale interfaccia.
Così soddisfiamo un altro principio

DIP - Dependency inversion Principle


Le classi dovrebbero dipendere da astrazioni, non da dettagli concreti.

Sistemi
Bisogna realizzare applicazioni che non conoscono il processo di costruzione per il
loro avvio. Quindi le loro dipendenze devono essere soddisfatte a monte.

Abstract Factory
Permette di mantenere i dettagli della costruzione degli oggetti separati dal codice
dell'applicazione.

Dependency Injection
Un oggetto non ha la responsabilità di procedere ad instanziare ogni sua
dipendenza (oggetti passivi).

Simple design
Codice pulito?

Passare tutti i test.

Clean Code Notes 5


Non contiene duplicazioni.

Esprime lo scopo del programmatore.

Minimizza il numero di classi e metodi.

Concorrenza
La concorrenza aiuta a disaccoppiare che cosa viene fatto da quando viene fatto.
Mantenere il codice che gestisce la concorrenza separato dall'altro codice.

Fate in modo che le sezioni sincronizzate siano le più piccole possibili, non tentate di
risolvere contemporaneamente i bug del codice a thread e di quello mono-thread.
Assicuratevi che il vostro codice funzioni indipendentemente dai thread.
Curate la versatilità del codice a thread, in modo da poterlo eseguire con varie
configurazioni.

Clean Code Notes 6

Potrebbero piacerti anche