Inserito da: msolcia | Marzo 5, 2009

Refactoring e cattivi odori nel codice (code smells)

Tanto per cambiare ho iniziato un nuovo libro “Refactoring Workbook” . Userò il blog come una sorta di block notes per prendere qualche appunto sul argomento.

Cos’è il refactoring?

E’ l’arte di migliorare il design del codice esistente e funzionante.

Cosa non è considerato refactoring?

1) Aggiungere funzionalità; sebbene il refactoring possa far parte di alcune tecniche come il TDD che lo usano per aggiungere nuove funzionalità, esso non ha come fine la creazione di nuove funzionalità,

2) Riscrivere il codice dall’inizio. Il Refactoring preferisce bilanciare meglio il codice già esistente senza prendersi il rischio di riscrivere codice nuovo potenzialmente non funzionante.

3) Un completo stravolgimento del codice che lo mantiene “non funzionante” oltre una normale sessione di lavoro. Il refactoring viene fatto a piccoli step alla volta, step magari molto frequenti ma che mantengono sempre funzionante il codice risultante.

Se pensiamo che vi sono due tipi di design: l’up-front design, cioè il design che viene deciso ancor prima di scrivere il codice e l’emerging design che è intrinsecamente connesso al codice che scriviamo, il refactoring cerca di abbassare il rischio ed il costo di quest’ultimo.

La metafora dei cattivi odori nel codice (code smells)

Nella vita quotidiana un cattivo odore richiama la nostra attenzione. La causa del cattivo odore può essere un problema oppure una cosa normale. L’intensità stessa dell’odore in alcuni casi ci da la certezza del problema, in altri casi no. Alcuni odori coprono altri odori, alcuni odori se ne vanno risolvendo altri problemi non direttamente collegati. Per ogni smell è importante saper riconoscere i sintomi, le cause, saper cosa fare, payoff e conoscere le controindicazioni (cioè in alcuni casi la medicina potrebbe uccidere il paziente :-( ).

Il code smell dunque descrive un problema localizzato nel codice e come tale non vi è garanzia, una volta fissato quel problema, di aver risolto completamente. Per questo motivo il fixing di uno smell viene fatto in maniera iterativa/incrementale con il seguente ciclo (loop):

Il ciclo di refactoring

1) si considera un programma funzionante,

2) Finché vi è puzza di codice marcio :-)

2.a) Si sceglie il codice con il puzzo peggiore,

2.b) Si seleziona la tecnica di refactoring appropriata e la si usa

3) Si ritorna al punto 2.

La difficoltà di questo processo è quella di riconoscere gli smells nonché riuscire a classificarli in base alla gravità (punto due).

Come approccio si può iniziare a fattorizzare le cose più macroscopiche (es. rinominare variabili/metodi con nomi più chiari o dividere i metodi che hanno più di 30 righe di codice in sotto-metodi).

Sempre il punto due dice “finché”, ma come si capisce che si è finito?

Kent Beck utilizza il concetto di Simple Design: se il codice non rispetta le 4 regole seguenti vi è un problema di sistemare. Il design è semplice quando il codice:

1) Passa tutti i test,

2) Non ha al suo interno logica duplicata,

3) Fa capire chiaramente il proprio intento a chi legge il codice,

4) Ha il minor numero di classi e metodi

Il simple design va constantemente mantenuto. Proprio in questi giorni sto rifattorizzando una serie di classi del nostro prodotto che sono state lasciate crescere a dismisura (metodi di 100+ righe) e la fatica che sto facendo per rifattorizzare tutto, sarebbe stata sicuramente minore se l’avessi fatta man mano che il codice cresceva.

Dove si situa il refactoring all’interno dei metodi di sviluppo agile?

Il refactoring è una tecnica che vive di vita propria, nel senso non è necessario imparare metodi di sviluppo agile per poterla usare. Nonostante questo ad esempio l’eXtreme Programming con il test-driven development (TDD) ne fa uno dei sue tre pilastri (insieme a Simple Design e test-first programming). In questi casi codice creato usando TDD richiede minor attività di refactoring.

Come si pratica il refactoring?

Strumenti: è sufficiente un editor di testi, anche oggi giorno ci si può avvalere di strumenti più sofisticati come l’editor di Visual Studio (o tool come Resharper) che consentono di automatizzare alcuni tipi di refactoring.

Persone: è meglio praticare il refactoring in team (o in coppia). In questo modo le diverse esperienze delle persone del team consentono di generare molte più idee/soluzioni rispetto al singolo.

Tests: una suite di test è indispensabile per avere una rete di salvataggio nel caso alcune modifiche cambino il design del software. Sul mercato vi sono numerosi framework che aiutano a costruire i test.

UML, CRC: il refactoring non sostituisce il design up-front

Configuration management/Version Control: questi strumenti sono importanti per poter confrontare le diverse versioni del codice dopo i diversi passi di refactoring. Grazie ad essi è anche possibile effettuare degli undo dei refactoring che hanno erroneamente cambiato il design o eseguire un refactoring con modalità trying&error.

Bene questa la teoria, ora non rimane che fare un po’ di pratica.


Lascia un commento

La tua risposta:

Categorie