Introduzione

Di solito facciamo refactoring: per migliorare la progettazione, rendere il codice più semplice da capire e ci permette di capire se ci sono eventuali bug.

Come si fa refactoring:

  • creare dei test validi, e verificare che il codice “sporco” attuale li passi
  • usando le varie tecniche di refactoring
  • verifica che tutti i test dopo il refactoring siano ancora superati
  • Se questo non succede allora il refactoring ha compromesso qualcosa che non funzionava

Quando fare refactoring: facciamo refactoring quando si presentano vari sintomi (code smell) e in base a questo usiamo la tecnica migliore

  • Codice duplicato: usiamo la tecnica Estrai Metodo
  • Metodi lunghi(o con commenti all’interno): usiamo la tecnica Estrai Metodo
  • Classi di grandi dimensioni: usiamo la tecnica Estrai Classe
  • Lunga lista di parametri: Introduciamo un oggetto parametro

Quando scriviamo una classe non è più importante creare i metodi set e get, esiste un tipo di classe chiamato Records che lo fa in automatico

Tecniche di seguito:

  • Estrai metodo
  • Estrai classe
  • oggetto parametro
  • Sostituisci temp con query

Estrai Metodo

Generale

Un frammento di codice può essere raggruppato sotto il nome di una funzione il cui nome ne spiega lo scopo

Motivazione

Le motivazioni sono diverse ma tre le principali troviamo la riscrittura di metodi lunghi in metodi più corti, quando si fa questa cosa con tutti i metodi, sembra quasi che i metodi di più alto livello (quelli che chiamano altre funzioni) siano formati da una di comment che descrivono esattamente quello che fa quel metodo, come vediamo nel metodo ‘printConto’.

Meccanismi

Di seguito gli step da seguire per applicare questa tecnica

  1. Creare un nuovo metodo il cui nome comunica l’intenzione del metodo
  2. Copiare il codice estratto
  3. Guardare se il codice estratto ha variabili locali nel metodo sorgente e nel caso farli diventare parametri del nuovo metodo
  4. Se alcune variabili sono locali del nuovo metodo farle diventare variabili temporanee
  5. Se il codice estratto modifica una variabile locale del metodo originario, dobbiamo vedere se è possibile mettere come valore di ritorno della funzione estratta quel valore. (Metodo sostituisci temp con query)
  6. Sostituire nel metodo sorgente il codice estratto con una chiamata al metodo nuovo

Sostituisci temp con query

Generale

Una variabile temporanea è usata per tenere il risultato di un espressione, per migliorare questa situazione dobbiamo:

  • Estrarre l’espressione ed inserirla in un metodo
  • Sostituire tutti i riferimenti a temp con la chiamata al metodo che incapsula l’espressione
  • Il nuovo metodo può essere richiamato anche altrove
Motivazioni
  • le variabili locali inducono ad avere metodi lunghi perché possono essere viste solo all’interno del contesto del metodo
  • sostituendo con la query, qualsiasi metodo può avere quel valore se necessario
  • Questo refactoring è semplice se la variabile è assegnata
Meccanismi
  • Cercare una variabile temporanea
  • Dichiarare temp final
  • Compilare (per vedere che è assegnata una volta sola)
  • Estrarre la parte destra dell’assegnazione e creare un metodo

Dividere variabile temp

Una variabile temporanea è assegnata più di una volta, ma non è una variabile assegnata in un loop o usata per accumulare valori, quello che dovremmo fare è usare una una variabile separata per ogni assegnamento Perdiamo di efficienza ma il codice è più pulito

Motivazioni

Se le variabili hanno più di una responsabilità all’interno di una funzione non va bene, una variabile temporanea deve avere un singola responsabilità, perché usare la stessa variabile per cose diverse confonde il lettore

Meccanismi
  • Cambiare il nome della variabile
  • Dichiarare la nuova come final
  • Cambiare tutti i riferimenti a temp fino alla sua seconda assegnazione
  • Dichiarare una nuova temp per la seconda assegnazione
  • Compilare e testare
  • Ripetere per singoli passi, ogni passo rinomina una dichiarazione e cambia i riferimenti fino alla prossima assegnazione

Generale

Questi tre metodi devono essere usati in questo ordine:

  1. Sostituisci temp con query
  2. Dividere variabile temp
  3. Estrai metodo

Sposta metodo

Generale

Un metodo usa più caratteristiche di un’altra classe che non di quella in cui è definito

Motivazioni
  • Spostare un metodo rende le responsabilità delle classi più chiare
  • Due classi sono strettamente accoppiate
Meccanismi
  • Esaminare attributi e metodi usati dal metodo da spostare per decidere se spostare anche questi (spostarli se sono usati solo dal metodo trasferito)
  • Controllare che il metodo da spostare non sia dichiarato anche in superclassi e sottoclassi
  • Dichiarare il metodo nella classe target
  • Copiare il metodo nella classe target e sistemare le chiamate a metodi della classe origine e della classe target
  • Richiamare il metodo nella classe target con l’opportuno riferimento
  • Decidere se rimuovere il metodo originario o tenerlo per delegare (chiamare al suo interno il nuovo metodo nell’altra classe)

Estrai classe

Generale

Una classe fa il lavoro che dovrebbero fare due classi

  • la classe Persona ha attributi per tenere prefisso e numero di telefono
Meccanismi
  • Decidere quali responsabilità separare
  • Creare una nuova classe per tali responsabilità
  • Inserire una dipendenza tra la vecchia e la nuova classe: un attributo nella vecchia classe che tiene una istanza della nuova classe
  • Spostare attributi e metodi dalla vecchia classe alla nuova classe, iniziando dai metodi di più basso livello
Motivazioni
  • Una classe dovrebbe avere una responsabilità, ma durante lo sviluppo si aggiungono attributi e metodi e la classe cresce
  • Una classe grande è difficile da comprendere
  • Se un sotto-insieme di dati ed un sotto-insieme di metodi dovrebbero andare insieme, o se un sotto-insieme di dati di solito viene cambiato insieme, o tali dati dipendono tra loro, allora è bene dividere la classe
  • Un altro segno è che la sottoclasse di tale classe coinvolge solo poche caratteristiche della classe