Fork me on GitHub
con Valerio Galano

Il podcast dove si ragiona da informatici

Un informatico risolve problemi, a volte anche usando il computer

Riflessioni e idee dal mondo del software

Episodio del podcast

Introduzione al Refactoring: migliorare il codice esistente

18 settembre 2019 Podcast Episodio 17 Stagione 1
Introduzione al Refactoring: migliorare il codice esistente

Descrizione

Il Refactoring, una fase del processo di sviluppo del software troppo spesso sottovalutata. A cosa serve? Quali vantaggi porta al nostro codice?

Fonti:
Martin Fowler - Refactoring - https://amzn.to/3c0lU0X

VOTA CON UN LIKE -> http://vota.pensieriincodice.it

Festival del podcasting
https://festivaldelpodcasting.it/

Attrezzature:
Microfono Blue Yeti* - https://amzn.to/3kSE35f
Filtro anti-pop* - https://amzn.to/3baPMsh
Filtro anti-pop* - https://amzn.to/2MH0Wf1
Schermo fonoassorbente* - https://amzn.to/3sOZE0P

Sostieni il progetto

Sostieni tramite Satispay
Sostieni tramite Revolut
Sostieni tramite PayPal
Sostieni utilizzando i link affiliati di Pensieri in codice: Amazon, Todoist, ProtonMail, ProtonVPN, Satispay

Partner

GrUSP (Codice sconto per tutti gli eventi: community_PIC)
Schrödinger Hat

Crediti

Montaggio - Daniele Galano - https://www.instagram.com/daniele_galano/
Voce intro - Costanza Martina Vitale
Musica - Kubbi - Up In My Jam
Musica - Light-foot - Moldy Lotion
Cover e trascrizione - Francesco Zubani

Mostra testo dell'episodio

Nascondi

Quella che segue è una trascrizione automatica dell'episodio.

Pensieri in codice, idee dal mondo del software a cura di Valerio Galano. Buongiorno a tutti e ben ritrovati qui su Pensieri in codice, il podcast in cui parliamo di argomenti presi dal mondo del software, di internet e della programmazione. Prima di iniziare con l’argomento di oggi volevo ricordarvi un paio di cose. La prima è che Pensieri in codice è candidato come podcast emergente del 2019 e se volete darmi una mano a scalare la classifica allora mettete un attimo in pausa questo episodio e andate sul sito vota.pensieriincodice.it, vi lascio anche il link in descrizione e vi apparirà un post Instagram al quale non dovrete fare altro che mettere un like. Vi ricordo inoltre che il 12 ottobre 2019 sarò a Milano per il festival del podcasting, quindi se vi va può essere un’occasione per incontrarci e passare un po’ di tempo insieme. Per organizzarci potete contattarmi sia su Instagram che sul gruppo Telegram, trovate tutti i link in descrizione. Ora però bando alle ciance e iniziamo con l’argomento di oggi. Qualsiasi programmatore che si sia mai trovato nella condizione di dover modificare del codice scritto tempo addietro sa bene che molto spesso tale codice può rivelarsi piuttosto complicato da mantenere e può richiedere un tempo considerevole per l’aggiunta di nuove funzionalità. Non importa che magari siamo stati noi stessi a scrivere il codice che ora stiamo cercando di modificare, se non abbiamo messo in atto delle strategie necessarie per renderlo leggibile allora probabilmente incontreremo un bel po’ di difficoltà. Noi ne abbiamo già parlato nell’episodio numero 5, quello sulla qualità del codice, che nel caso non abbiate ascoltato vi invito a recuperare e vi metto il link in descrizione. In questo episodio abbiamo detto che un codice poco chiaro rallenta lo sviluppatore e addirittura in casi estremi può portare persino i progetti al fallimento. In quello stesso episodio parlavamo anche del fatto che ci fossero delle tecniche da tenere a mente e da applicare durante la scrittura del codice così da poter evitare di avere eccessivi problemi in futuro. Tuttavia se ormai ci troviamo a lavorare su un codice già esistente che però soffre di queste limitazioni dovute alla scarsa qualità è il refactoring, quell’attività che può venirci in aiuto e salvarci la giornata. Il refactoring è infatti quella fase del processo di sviluppo che consiste nel operare sul codice al fine di migliorarlo e renderlo più leggibile. Si tratta in pratica di una serie di piccole operazioni da applicare una dopo l’altra per trasformare quello che è un codice confuso e magari poco comprensibile in qualcosa che sia facilmente leggibile da chi dovrà lavorarci su. E attenzione io ho usato le parole serie di piccole operazioni ma non lasciatevi ingannare perché Martin Fowler nel suo libro Refactoring, di cui vi lascio un link in descrizione, individua e descrive approfonditamente e con abbondanti esempi oltre 70 tecniche diverse che possono essere applicate ad un codice per migliorarne la leggibilità. Ovviamente non tutte queste tecniche possono essere applicate insieme e serve una chiara comprensione di ciascuna per capire quando esse siano necessarie, quando sia possibile applicarle e quando valga effettivamente la pena di farlo. Questa serie di cambiamenti però interessano solo specifiche porzioni del codice e devono essere eseguite in modo da non intaccare né il funzionamento né l’utilizzo da parte degli altri e per altri intendo sia i programmatori che quel codice lo utilizzano sia altro codice che si appoggia ad esso per elaborare un qualcosa. Questo vuol dire che quando io faccio Refactoring su una porzione di codice allora potrò modificare solo la struttura interna di tale codice, salvo ovviamente particolari casi che approfondiremo magari in un altro episodio. Ad esempio se ho una libreria che prende in input una serie di dati e sulla base di essi restituisce un certo output, dopo che ne avrò ristrutturato il codice molto probabilmente questa libreria sarà estremamente differente al proprio interno ma dovrà comunque continuare a prendere in input quei dati e restituire quello stesso output. Per semplificare al massimo immaginiamo un software che calcola il perimetro di un quadrato prendendo in input la lunghezza del lato. Ovviamente è difficile sbagliare il codice di un programma così semplice ma fingiamo che sia stato scritto in modo poco chiaro. Se noi volessimo applicare un’operazione di refactoring potremmo cambiare completamente il codice del software a patto che esso continui a prendere la larghezza del lato in input e continui a restituire il perimetro del quadrato corrispondente. Dunque la definizione che anche lo stesso Fowler dà nel proprio libro è qualcosa del genere. Il refactoring è quell’operazione di ristrutturazione della struttura interna di un codice che ha il fine di renderlo più facile da capire e da modificare senza cambiarne il comportamento osservabile. Dal punto di vista pratico per poter ottenere un risultato del genere magari operando su un codice complesso e senza provocare danni il refactoring si applica come un susseguirsi di piccole modifiche seguite da test completi delle funzionalità. Quindi va da sé che disporre di una buona batteria di test automatizzati può aiutare enormemente nelle operazioni perché in pratica quando ristruttureremo il nostro codice opereremo nel seguente modo. Applicheremo una modifica magari estrarremo un parametro da una funzione o sposteremo delle righe in un metodo esterno e poi lancieremo tutti i test per assicurarci che tutto funzioni ancora come prima. Poi faremo un’altra piccola modifica e via di nuovo con i test e così via fino al termine delle modifiche. A seconda della quantità di codice da ristrutturare quindi l’attività di refactoring può richiedere un impegno non indifferente e portare via molto tempo allo sviluppatore. Per questo motivo e anche perché non stiamo parlando di un’attività meccanica ma di qualcosa che richiede molta concentrazione è sconsigliato cercare di affiancarla ad altri processi come ad esempio la scrittura di nuovo codice. Secondo Fowler, ma su questo anch’io mi trovo perfettamente d’accordo, lo sviluppatore deve dedicarsi separatamente alle operazioni di aggiunta di funzionalità e a quella di refactoring senza cercare di sistemare un po’ di codice vecchio qui e là mentre lavora il codice nuovo. Ciò renderebbe infatti più pesante lo sviluppo nonché rischierebbe di introdurre nuovi bug e rendere anche più difficile identificarne l’origine che a questo punto potrebbe essere imputabile sia al nuovo codice che a quello ristrutturato. Questa separazione tuttavia è la ragione principale per cui il refactoring viene considerato un’attività di secondo ordine rispetto allo sviluppo e viene spesso bisfrattata e ignorata in fase di pianificazione. D’altronde ad un occhio poco attento un’attività che impiega lo sviluppatore per giorni ma non produce alcuna modifica evidente nel comportamento del codice può facilmente apparire come inutile ed essere etichettata come una perdita di tempo. Tuttavia la verità è che il refactoring anche se non produce nuove funzionalità ha il grande merito di trasformare cattivo codice in codice di qualità e ciò esattamente come dicevamo nell’episodio 5 porta a enormi risparmi di tempo quando si deve appunto manutenere o modificare quel codice. Perdere un po’ di tempo a ristrutturare un codice oggi può significare risparmiare tantissimo quando poi sarà necessario aggiungere delle funzionalità a quel codice o quando sarà necessario aggiornarlo e questo miglioramento in fase di sviluppo e manutenzione è la conseguenza di tre principali effetti del refactoring. Il primo di questi effetti consiste nel fatto che le operazioni di ristrutturazione conducono quasi automaticamente ad una rimozione delle duplicazioni nel codice. Isolare le responsabilità dei metodi, diminuire il numero di istruzioni, trasferire i dati tramite parametri e tante altre piccole trasformazioni del genere portano ad ottenere un codice più facile da riutilizzare e quindi diminuisce la necessità di avere più codice ogni qual volta si debbano eseguire due operazioni simili. Capita spesso infatti che quando si sviluppa non si abbia una conoscenza totale della codebase cioè dell’insieme di codice che compone il progetto e senza saperlo si scriva un codice molto simile ad uno già esistente oppure capita di dover fare in più punti operazioni molto simili ma di non avere la possibilità di eseguire lo stesso codice dappertutto e quindi lo si riscrive quasi uguale. In fase di refactoring tutte queste piccole imperfezioni vengono sistemate e il risultato è quello di avere le stesse funzionalità con meno righe di codice e questo ci porta direttamente alla seconda conseguenza del processo di refactoring. Meno codice più isolato e meglio descritto rende il tutto più leggibile e comprensibile all’occhio umano. In questo modo lo sviluppatore che capiterà a lavorare su quella porzione di codice non dovrà dannarsi per capire quali funzionalità svolge, potrà essere più produttivo e il suo lavoro sarà anche più piacevole. Infine la terza conseguenza dell’applicazione del refactoring renderà anche più evidenti eventuali bug. Infatti in una funzione circoscritta che ha un unico compito da svolgere e lo fa con poche istruzioni è molto più semplice individuare un errore di logica nelle operazioni. In definitiva per come la vedo io fare refactoring conviene sempre ed è un’attività da prevedere pianificare al pari dell’analisi dello sviluppo dei test eccetera. Applicandola nei miei progetti ho anche potuto notare che è più conveniente se fatta a distanza di qualche tempo dall’inizio dei lavori. Questo perché scrivere del codice e subito dopo ristrutturarlo spesso porta alla necessità di altre ristrutturazioni in futuro mentre attendere di aver compreso al meglio il dominio del progetto e di aver scritto una buona parte della codebase secondo me rende più produttivo l’impiego di tempo perché c’è più materiale su cui lavorare e una maggiore visione d’insieme. Anche per oggi siamo giunti alla fine di questo episodio io vi ringrazio per essere arrivati fin qui e vi invito a farmi sapere la vostra opinione sull’argomento sia commentando che unendovi al gruppo telegram sul quale stiamo avendo un sacco di discussioni interessanti trovate tutti i link in descrizione. Se il podcast vi piace inoltre vi chiedo di condividerlo il più possibile e di farlo conoscere a chi potrebbe essere interessato. Vi ricordo di andare a votare pensieri in codice per il contest e se volete maggiori informazioni sul festival del podcasting potete visitare il sito festivaldelpodcasting.it. Direi che per oggi è tutto io vi saluto vi ringrazio e vi do appuntamento ad un prossimo episodio.

Nascondi