Il code refactoring in Ingegneria del Software

In Ingegneria del Software, il code refactoring (o semplicemente refactoring) è una tecnica disciplinata e molto utilizzata per ristrutturare porzioni di codice esistente, riorganizzando la struttura interna senza modificarne il comportamento esterno. Si tratta di un elemento importante delle principali metodologie emergenti di sviluppo software (soprattutto nella programmazione object-oriented), tra l’altro utilizzato per per migliorare: la leggibilità, la manutenibilità, l’estensibilità, la riusabilità e per ridurre la complessità del codice.

Alla base del metodo ci sono una serie di piccoli comportamenti che preservano le trasformazioni. Ogni trasformazione (chiamata “refactoring”) fa poco, ma una sequenza di queste trasformazioni può produrre una ristrutturazione significativa. Poiché ogni refactoring è piccolo, è meno probabile che vada storto. Il sistema viene mantenuto completamente funzionante dopo ogni refactoring, riducendo le possibilità che un sistema possa essere seriamente danneggiato durante le operazioni di ristrutturazione del codice.

Il code refactoring riduce il costo dei miglioramenti

Quando un sistema software ha successo, è sempre necessario continuare a migliorarlo, risolvere i problemi e aggiungere nuove funzionalità. Ma la scrittura del codice fa una grande differenza su quanto sia facile apportare queste modifiche. Spesso i miglioramenti vengono applicati uno sopra l’altro in un modo che rende sempre più difficile apportare modifiche. Con il passare del tempo il nuovo lavoro rallenta a passo d’uomo. Per contrastare questo rallentamento, è importante effettuare il refactoring del codice in modo che le modifiche aggiunte non portino a complessità inutili.

Il code refactoring fa parte della programmazione quotidiana

Il refactoring non è un’attività speciale che verrebbe visualizzata in un piano di progetto. Fatto bene, è una parte regolare dell’attività di programmazione. Quando ho bisogno di aggiungere una nuova funzionalità ad uno script, guardo il codice esistente e valuto se è strutturato in modo tale da rendere semplice la nuova modifica. In caso contrario, eseguo il refactoring del codice esistente per semplificare questa nuova aggiunta. Effettuando prima il refactoring in questo modo, di solito trovo che sia più veloce che se non avessi eseguito prima questa operazione.

Solo dopo aver apportato tale modifica, aggiungo la nuova funzionalità. Dopo aver aggiunto una funzionalità e averla fatta funzionare, noto spesso che il codice risultante, sebbene funzioni, non è così chiaro come potrebbe essere. Quindi è possibile effettuare di nuovo il refactoring del codice portandolo in una forma migliore in modo che quando io (o qualcun altro) tornerò a modificare il codice, non dovrò perdere tempo a scervellarmi su come funziona questo codice. In questa operazione di riorganizzazione del codice, oltre alla struttura del codice, cercando di portare a fattor comune il codice duplicato, mi aiuto lasciando dei commenti prima di una funzione o prima di una operazione o porzione di codice particolare.

Quando modifico un programma, spesso cerco altrove nel codice, perché gran parte di ciò che devo fare potrebbe essere già codificato nel programma. Se faccio fatica a capire questo codice, procedo con il refactoring in modo da non dover lottare di nuovo la prossima volta che lo guardo. Se sono nascoste alcune funzionalità di cui ho bisogno, eseguo il refactoring in modo da poterle utilizzare facilmente.

Esempi di code refactoring su GitHub

Su GitHub al link (https://github.com/RefactoringGuru/refactoring-examples/tree/master/simple) è possibile visionare una serie di esempi, sviluppati nei lingaggi di programmazione C#, java, php, python e typescript. Gli esempi, sono sviluppati e aggiornati dalla community Refactoring.Guru e mostrano come il codice venga modificato a seguito di operazioni di refactoring, creando un file con lo script prima (seguito dal nome BEFORE) e dopo (con il nome AFTER) delle operazioni di code refactoring. Tra le principali attività, per ognuno dei linguaggi di programmazione, troviamo le seguenti operazioni:

  • consolidate conditional expression
  • consolidate duplicate conditional fragments
  • decompose conditional
  • encapsulate field
  • extract class
  • extract method
  • extract method decompose loop
  • extract method isolate switch
  • extract variable
  • inline method
  • introduce assertion
  • introduce foreign method
  • introduce null object
  • move method isolate switch
  • preserve whole object
  • pull up constructor body
  • remove assignments to parameters
  • rename method
  • replace array with object
  • replace conditional with polymorphism
  • replace constructor with factory method
  • replace error code with exception
  • replace exception with test
  • replace magic number with symbolic constant
  • replace method with method object
  • replace nested conditional with guard clauses
  • replace parameters with explicit methods
  • replace parameters with method call
  • replace temp with query
  • self encapsulate field
  • split temporary variable
  • substitute algorithm

Gli strumenti automatizzati sono utili, ma non essenziali

Molti linguaggi hanno IDE che automatizzano molti refactoring comuni. Queste sono una parte davvero preziosa del mio toolkit che mi consente di eseguire il refactoring più velocemente. Ma tali strumenti non sono essenziali: spesso lavoro in linguaggi di programmazione senza il supporto di strumenti, nel qual caso mi affido a piccoli passi e uso di test frequenti per rilevare gli errori.

Sul sito (https://refactoring.com/) a cura di Martin Fowler, che è tuttora uno degli autori più influenti sull’argomento, è possibile visionare un catalogo delle principali operazioni di refactoring applicabili su porzioni di codice.

Testi consigliati su il code refactoring

Per approfondire l’argomento del code refactoring, consiglio seguenti testi tutti ad opera di Martin Fowler, disponibili alcuni in italiano e altri solo in lingua inglese.

Refactoring: Improving the Design of Existing Code (English Edition)

di Martin Flower
Ed. Addison-Wesley Professional
L’arte del Refactoring: Guida alle tecniche per migliorare il design e la leggibilità del codice

di Martin Flower
Ed. Apogeo
Patterns of Enterprise Application Architecture (English Edition)

di Martin Flower
Ed. Addison-Wesley Professional

Links Utili

[https://it.wikipedia.org/wiki/Refactoring]

L’argomento del code factoring è spiegato in maniera chiara e sintetica

[https://refactoring.com]

Raccolta di risorse sul refactoring mantenuta da Martin Fowler

[https://martinfowler.com]

Blog personale di Martin Fowler, uno degli autori più influenti sul code refactoring