Simyl
simylflow
Home del Corso
Modulo 2: Pratiche Tecniche
Lezione 3 di 5
12 min

Refactoring

Migliorare il codice senza cambiarne il comportamento. La disciplina che mantiene sane le codebase.

1Cos'è il Refactoring (e Cosa Non È)

Il refactoring consiste nel migliorare la struttura interna del codice senza modificarne il comportamento esterno.

Questa definizione ha due parti fondamentali:

Migliorare la struttura: Rendere il codice più facile da comprendere, modificare o estendere. Questo include nomi migliori, funzioni più piccole, organizzazione più chiara, meno duplicazione.

Senza modificare il comportamento: Il codice fa esattamente ciò che faceva prima. Gli input producono gli stessi output. Gli effetti collaterali sono identici. I test continuano a passare.

Il refactoring non è:

  • Riscrivere da zero
  • Aggiungere funzionalità
  • Correggere bug
  • Ottimizzazione delle prestazioni (di solito)

Se stai cambiando ciò che fa il codice, non stai facendo refactoring—stai facendo qualcos'altro. Il refactoring riguarda specificamente la struttura, non il comportamento.

Il refactoring è come pulire la cucina. Il cibo ha ancora lo stesso sapore. Ma cucinare diventa più facile, veloce e meno frustrante.

2Il Catalogo del Refactoring

Martin Fowler ha documentato dozzine di refactoring specifici, ciascuno con:

  • Un nome (così i team possono comunicare)
  • Una motivazione (quando usarlo)
  • Meccaniche (passo dopo passo come farlo in sicurezza)

Ecco alcuni che userai costantemente:

Extract Function: Prendi del codice e mettilo in una nuova funzione con un nome chiaro. Questo è probabilmente il refactoring più comune.

Rename: Cambia il nome di una variabile, funzione o classe per esprimere meglio il suo scopo. I buoni nomi sono sorprendentemente importanti.

Inline Function: L'opposto di extract—sostituisci una chiamata di funzione con il suo corpo. Usa quando una funzione non aggiunge chiarezza.

Extract Variable: Prendi un'espressione complessa e dalle un nome assegnandola a una variabile.

Move Function: Sposta una funzione in una classe dove ha più senso.

Replace Conditional with Polymorphism: Sostituisci complessi if/else o switch con dispatch orientato agli oggetti.

Questi non sono refactoring "avanzati". Sono strumenti quotidiani. Imparali finché non diventano automatici.

3Fare Refactoring in Sicurezza

Il refactoring è sicuro solo quando hai i test. Senza test, ogni modifica potrebbe rompere qualcosa, e non lo saprai fino alla produzione.

Il processo di sicurezza:

  1. Assicurati che i test passino prima di iniziare
  2. Fai una piccola modifica
  3. Esegui i test
  4. Se i test passano, continua; se falliscono, ripristina immediatamente
  5. Ripeti

I piccoli passi sono fondamentali. Non cercare di fare refactoring di cinque cose contemporaneamente. Estrai una funzione, esegui i test, committa. Rinomina una variabile, esegui i test, committa. In questo modo, se qualcosa si rompe, sai esattamente cosa l'ha causato.

Gli IDE moderni hanno refactoring automatizzati che sono più sicuri delle modifiche manuali. "Rename" nel tuo IDE aggiorna tutti i riferimenti. "Extract Function" crea la funzione e aggiorna il punto di chiamata. Usa questi strumenti.

La Regola del Boy Scout: Lascia il codice migliore di come l'hai trovato. Quando tocchi il codice per qualsiasi motivo, fai un piccolo miglioramento. Nel tempo, la codebase diventa più pulita invece che più sporca.

Nessun Test = Nessuna Sicurezza

Il refactoring senza test è solo cambiare codice e sperare. Non è refactoring—è scommettere.

4Quando Fare Refactoring

Fai refactoring costantemente. Il refactoring non è una fase separata o uno sprint. È continuo.

Trigger specifici per fare refactoring:

Prima di aggiungere una funzionalità: Se la struttura attuale rende difficile aggiungere la funzionalità, fai prima refactoring. Rendi facile il cambiamento, poi fai il cambiamento facile.

Dopo aver fatto passare un test: Questo è il "refactor" in red-green-refactor. Pulisci prima di passare al test successivo.

Quando noti un code smell: Codice duplicato, metodi lunghi, nomi poco chiari, condizionali complessi—questi sono segnali che serve refactoring.

Durante la code review: Se vedi qualcosa che miglioreresti, fallo o annotalo per dopo.

Quando hai tempo: Tieni un "backlog di refactoring" di problemi noti. Quando hai tempo, prendi qualcosa dalla lista.

Non fare refactoring quando:

  • Non hai test
  • Stai per rilasciare (stabilizza, non cambiare)
  • Non capisci cosa fa il codice (prima capisci)

5Debito Tecnico e Refactoring

Il debito tecnico è il costo accumulato di prendere scorciatoie. Ogni volta che dici "lo pulirò dopo" e non lo fai, aggiungi debito. Ogni volta che fai copia-incolla invece di estrarre, aggiungi debito.

Il debito accumula interessi. Il codice disordinato richiede più tempo per essere modificato. I bug si nascondono nella complessità. I nuovi membri del team faticano a capire. Il costo del cambiamento aumenta.

Il refactoring è come ripaghi il debito. Il refactoring regolare mantiene il debito gestibile. Trascurare il refactoring lascia che il debito si accumuli fino a quando la codebase diventa ingestibile.

L'intuizione chiave: Il refactoring non è un lusso. È manutenzione essenziale. Non chiedi il permesso di ripagare il debito—lo fai semplicemente come parte del tuo lavoro.

XP integra il refactoring nel processo. Ogni funzionalità, ogni correzione di bug, ogni task include tempo per lasciare il codice migliore di come l'hai trovato. Non hai bisogno di uno "sprint di refactoring"—hai bisogno di un'abitudine al refactoring.

Buona Pratica di Refactoring

Mentre correggi un bug, noti codice duplicato nelle vicinanze. Correggi prima il bug (modifica del comportamento), poi estrai la duplicazione in una funzione (refactoring). Due commit: correzione del bug, poi refactoring.

Refactoring Sbagliato

Mentre aggiungi una funzionalità, decidi anche di fare refactoring del sistema di autenticazione, riorganizzare la struttura delle cartelle e aggiornare lo schema del database. Perdi traccia di cosa è cambiato, i test falliscono misteriosamente e passi ore a fare debug.

Punti Chiave
  • Il refactoring migliora la struttura del codice senza modificarne il comportamento
  • I test sono essenziali—il refactoring senza test è solo cambiare codice e sperare
  • Fai piccoli passi: una modifica, esegui i test, ripeti
  • Usa la Regola del Boy Scout: lascia il codice migliore di come l'hai trovato
  • Il refactoring è continuo, non una fase separata—integralo nel lavoro quotidiano
Errori Comuni da Evitare
  • Fare refactoring e aggiungere funzionalità contemporaneamente (fai una cosa o l'altra)
  • Refactoring big-bang invece di piccoli passi
  • Refactoring senza test (troppo rischioso)
  • Chiedere il permesso per fare refactoring (fa parte del lavoro)

Esercizi Pratici