Quando si scrivono programmi si tende spesso a focalizzarsi sulla struttura del codice fin dall'inizio, in modo da scrivere sorgenti organici e facilmente mantenibili. Purtroppo durante il processo di sviluppo possono avvenire varie modifiche ai piani iniziali, magari dovuti da scadenze troppo strette oppure aggiunte dell'ultimo minuto. Di conseguenza il codice progettato inizialmente viene piano piano sporcato di patch ed aggiunte che a lungo termine rischiano di generare un programma poco leggibile e facilmente adattabile a future modifiche. Questa cosa è ancora più evidente nel caso in cui su un programma intervengano persone che utilizzano stili e strutture di programmazione differenti.
Il refactoring è un insieme di pratiche che vengono applicate al codice sorgente al fine di variarne la struttura senza cambiare le funzionalità dell'applicazione, al fine di avere sotto mano dei sorgenti facilmente mantenibile e comprensibili a chiunque ed anche dopo molto tempo.
Con questo articolo, in cui introdurrò teoricamente il refactoring, daremo il via ad una serie che si occuperà di trattare in modo teorico le più importanti tecniche di refactoring e di studiare come queste possono essere adattate a PHP.
I principi del Refactoring
Definire il termine refactoring risulta difficile anche per chi ha creato il termine e sta operando per standardizzarne le pratiche. Possiamo però descrivere brevemente com'è nato il refactoring e che vantaggi porta al programmatore, in modo che ognuno di voi, anche senza definizione, sia in grado di farsi un'idea del concetto.
Il refactoring è una pratica che solitamente viene applicata quando si parla di programmazione ad oggetti; è nato negli anni in cui Smalltalk era il linguaggio principe della programmazione ad oggetti, e le regole sono state sviluppate su questo paradigma. Applicare il refactoring significa modificare il codice sorgente di un programma con l'obiettivo di ottimizzarne la struttura e la leggibilità lasciandone invariate le funzionalità. Le pratiche di refactoring, applicate in modo metodico e con senno di poi, portano a un netto miglioramento della struttura e della leggibilità del codice, con successivi vantaggi dal punto di vista della velocità di sviluppo e del miglioramento della cooperazione tra collaboratori.
Le pratiche di refactoring, sebbene in modo indiretto possano portare ad un miglioramento delle prestazioni, non sono state pensate con questo obiettivo. Modificare i sorgenti con queste pratica porta spesso ad una diminuzione del codice sorgente con un conseguente aumento della leggibilità, ma non sempre un aumento delle prestazioni. Nei casi in cui le prestazioni siano un aspetto fondamentale esistono comunque regole che permettono di estrarre gli algoritmi da ottimizzare in modo che risultino ben separati dal resto della struttura ristrutturata.
Quando si pratica refactoring è importante non vederlo come un'operazione a sé stante, da eseguire alla fine del processo produttivo; ogni volta che si scrive una funzione è un buon momento per apportare refactoring, modificando il codice sorgente in modo che l'aggiunta della funzione avvenga nel modo più naturale possibile. Applicato le tecniche di refactoring direttamente durante la scrittura si otterranno netti miglioramenti dal punto di vista della produttività, soprattutto quando il codice inizia di diventare complesso dato che avremo sotto mano un codice ben organizzato e su cui sarà molto facile fare delle modifiche.
PHP ed il refactoring
Le pratiche di refactoring spesso non sono applicate ai progetti PHP, neanche a quelli più conosciuti. Questo è dovuto ad una serie di motivi:
- Il linguaggio non è strettamente tipizzato mente molte tecniche di refactoring lavorano su questo tipo di concetto. Di conseguenza è essenziale che in generale ci sia una buona qualità del codice e si cerchi di mantenere omogeneo il tipo di dato contenuto nelle variabili, in modo da facilitare le pratiche;
- PHP non è nato come linguaggio ad oggetti;
- Spesso il codice PHP viene inserito direttamente all'interno del codice HTML (cosa sconsigliata vivamente da anni ma ancora adottata) il che rende altamente complesso adattare i sorgenti alle pratiche di refactoring;
Data questa situazione è importante comprendere come le varie tecniche di refactoring debbano essere applicate nello specifico all'ambito PHP, prendendo in considerazione comunque che una separazione tra logica programmativa e visualizzazione è necessaria se si vuole poter operare in modo costruttivo.
Il refactoring ed il testing del codice
Le pratiche di refactoring vanno pari passo con il testing del codice. Indipendentemente dal fatto che si decida di utilizzare un determinato approccio dal punto di vista progettuale e dal punto di vista dell'approccio allo sviluppo, è bene sapere che le pratiche di refactoring sono ben integrate all'Extreme Programming (XP). L'XP racchiude molte pratiche programmative che ultimamente stanno guadagnando terreno tra gli sviluppatori, apportando innovazioni dal punto di vista del processo di progettazione, sviluppo e successivo mantenimento del software.
Quando si applicano delle modifiche al codice sorgente è probabile che si inseriscano degli errori nel codice. Nessuno è perfetto e spesso capita che una modifica in un punto generi un errore in un'altra parte del programma. Sviluppare tenendo sotto mano una buona suite di test è un ottimo sistema per limitare il tempo perso dietro il risolvere bug a catena o sviluppare delle patch che patchino le patch che avete sviluppato per la versione patchata del vostro software (il gioco di parole serve a rendere l'idea).
Ogni volta che aggiungete una funzione scrivete subito un piccolo test che controlli il suo funzionamento, poi sviluppate la funzione ed eseguitelo. Se tutto va bene siete sicuri che il codice inserito funziona (ovviamente il test deve essere fatto in modo da assicurarsi il funzionamento corretto) e che la modifica di questo non ha influito in modo distruttivo sul resto del codice. A mano a mano che aggiungerete funzioni aggiungerete test e alla fine vi ritroverete con una suite di test che potrete avviare ogni volta che ne avete bisogno per assicurarsi che tutto funzioni. Senza contare il fatto che, se il test avviato qualche ora prima funziona e quello corrente no, sicuramente sarete in grado di identificare più facilmente il problema, che sarà legato al codice aggiunto in questo lasso di tempo.
Quando applicate refactoring del codice eseguite spesso questi test; questo vi assicura che l'interfaccia del software sia sempre la stessa, e che tutto funzioni correttamente.
Dal prossimo articolo inizieremo con le tecniche più comuni di refactoring, e vedremo come queste possono essere adattate a PHP.