đ Introduzione
Nella lista dei must da leggere, Martin Fowler è sempre una certezza. Refactoring è un manuale piĂš che un libro nel quale vengono illustrati diversi pattern per poter affrontare un refactoring di codice legacy. Attenzione però che il focus è legato alla programmazione ad oggetti. Devo dire che fortunatamente dopo quasi 15 anni di programmazione molti pattern sono conosciuti e applicati di default. Però come al solito, avere un linguaggio comune con cui chiamarli è dâaiuto per accordarsi con i dev. Dâaltronde a noi del genere umano piace molto dare il nome alle cose!
đ Cosa mi porto a casa da questa lettura
- Il refactoring è una attivitĂ rischiosa perchè si va a modificare codice funzionante. Questo aspetto va preso bene in considerazione perchè per poter affrontare bene questo processo lâunica cosa che ci può proteggere sono i test.
- Lâobiettivo è quello di non modificare il comportamento esterno ma migliorare la struttura interna, perchè come espresso in libri come clean code e clean architecture di Robert C. Martin un sistema disegnato male è difficile da mantenere e da modificare
- LâattivitĂ di refactoring dovrebbe essere continua e fatta ad ogni nuova feature del codice, in modo che sia fatta per piccoli step e corredata da test. I piccoli step garantiscono che la superficie di impatto sia limitata da controllare. Mentre lâattivitĂ continua implica che nelle stime venga sempre messo in conto anche questa attivitĂ altrimenti il business difficilmente finanzierĂ questi tipi di attivitĂ che non hanno impatto sul cliente finale.
- Il primo refactoring che può dare massimo effetto con minimo sforzo è il renaming. Dare il nome giusto a metodi e a variabili rende il codice leggibile anche da chi lo vede per la prima volta.
- Eâ bene mantenere vecchi metodi, deprecarli e utilizzare al loro interno quelli nuovi. SarĂ poi successivamente che sarĂ possibile eliminare il metodo deprecato.
- La maggior parte dei refactoring tendono a diminuire il codice ma ove non possibile non bisogna aver paura di scrivere piĂš righe di codice. Lâobiettivo è quello di migliorare la struttura interna del codice. Questo significa che a volte è meglio avere un ciclo macchina in piĂš che del codice difficile da mantenere. In contesti non real time la cpu costa meno degli sviluppatori che devono lavorare su quella codebase.
- Dopo tre volte che duplichi il codice è meglio estrarlo in un metodo richiamato dai tre punti.
- Usare lâindirection (lâintroduzione di un elemento di disaccoppiamento tra due layer) permette di:
- abilitare la condivisione di logica
- rendere esplicita lâintenzione del progettista e separare lâimplementazione
- isolare le modifiche
- raggruppare logica condizionale
- Le interfacce sono dei strumenti di indirection potenti ma hanno il limite che una volta resi pubbliche o se vogliamo pubblicate il progettista ne perde il controllo perchÊ non può sapere a priori quali siano le implementazioni. Questo vale soprattutto per i framework e per questo un consiglio è quello di non pubblicare troppo presto le interfacce.
- Alcuni blocchi che facilmente possono essere considerati oggetto di refactoring sono:
- metodi lunghi
- classi larghe
- firme lunghe
- Quando senti il bisogno di scrivere un commento, prova prima a fare del refactoring in modo da rendere superfluo il commento.
- Separa lo strato di dominio da quello di presentazione.
- I test possono essere integrati nel codice usando in maniera appropriata le Assertion e le Exception. E quando si risolve un bug è buona norma affiancarlo da un unit test per verificarlo.
- Se si ritiene che un pezzo di codice debba essere riscritto⌠a quel punto non ha senso procedere con il refactoring ma semplicemente con la nuova implementazione
đŠ Elenco dei principali Code Smells
- Shotgun Surgery: Una qualsiasi modifica ad una classe implica una serie di mini modifiche in tanti oggetti.
- Feature Envy: Si ha quando un metodo di una classe tratta principalmente dei dati di unâaltra classe
- Primitive Obsession: si ha quando si usano solo campi primitivi invece di strutturare i dati in oggetti
- Switch Statements: gli switch case sono importanti ma se abusati o molto complessi vale la pena spezzarli in blocchi di if else then. Se si aggiunge una nuova clausola va poi rivisto tutto il flusso dei switch case
- Parallel Inheritance Hierarchies: avviene quando creando una sottoclasse di una classe câè la necessitĂ di creare una sottoclasse di unâaltra class.
- Lazy Class: se una classe non viene usata o non fa abbastanza allora vale la pena eliminarla e spostare la logica
- Speculative Generality: si ha quando si trovano metodi, classi, campi o parametri non usati o pensati per un futuro
- Temporary Field: si ha quando di un oggetto alcuni campi vengono popolati solo in certe circostanze
- Message Chains: si ha quando si vede una catena di oggetti che chiamano oggetti in sequenza: a() -> b() -> c()
- Inappropriate Intimacy: si ha quando una classe usa un metodo o campo interno di unâaltra classe
- Middle man: se una classe esegue solo unâazione allora vale la pena eliminarla. Spesso questa classe farĂ solo da tramite verso lâoggetto che realmente esegue la logica.
đ§ Elenco delle principali azioni di refactoring
- Composizione di metodi per aggregare logica in un solo blocco
- Estrazione a metodo di parte di logica ripetuta
- Rinominare metodi, variabili, campi
- Estrarre oggetti da metodi, da data value o da parametri
- Sostituzione di algoritmi
- Sostituire magic number con costanti.
- Estrarre interfacce e astrazioni.
- Introdurre lâoggetto Null.
- Sollevare eccezioni al posto di codici di errore
- Usare le asserzioni
đ Quando non scrivere un refactoring
- Quando non si sa bene come farlo
- Se i vantaggi a lungo termine non ne valgono la pena
- Se è troppo costoso
- Se può rompere il funzionamento
đˇ Conclusione
Martin Fowler è uno dei piĂš illustri scrittori di ingegneria del software e questo libro è un must. Può sembrare a volte banale per un programmatore scafato ma raccoglie in maniera ordinata tutta una serie di âcode smellsâ che possono essere risolti per migliorare la struttura del codice. Un ottimo strumento da utilizzare alla bisogna e in particolare da abbinare a questo sito che raccoglie anche visivamente delle schede sullâargomento: Refactoring Guru
đ¤ Riferimento
Martin Fowler, Refactoring: Improving the Design of Existing Code,  Addison-Wesley Professional, 2° edizione, 2020. Amazon.
âAny fool can write code that a computer can understand. Good programmers write code that humans can understand.â. (Martin Fowler)