Viste le richieste che mi sono state fatte nei commenti 
al mio precedente post, ho deciso di dare qualche dettaglio in più sulle 
tecniche di refactoring che ho utilizzato nella realizzazione di IMHO.
Occorre innanzitutto tenere presente che nelle fasi iniziali di sviluppo ho 
installato il Resharper. Questo tool, prodotto dalla stessa azienda che ha 
realizzato uno degli IDE più famosi per Java (IntelliJ IDEA), fornisce un bel 
po' di strumenti utili per rendere più agevole la scrittura del codice in VS.NET 
2003 e per fare del vero e proprio refactoring. Quella che preferisco in 
assoluto è la possibilità di aggiungere gli using automaticamente quando si 
inseriscono delle classi che non sono mai state utilizzate. Tuttavia dopo pochi 
giorni di lavoro mi sono visto costretto a disinstallare il tutto. A quanto pare 
Resharper ha la brutta abitudine di fagocitare quanto più RAM 
possibile e rende instabile e inutilizzabile Visual Studio. Questo probabilmente 
perchè ha la pretesa di sostituire totalmente l'intellisense di VS, invece che 
semplicemente aggiungere le funzionalità mancanti.
Quindi in breve mi sono trovato nudo. Nessuno strumento per poter fare del 
refactoring assistito, e la necessità come si suol dire ha aguzzato l'ingegno. 
La chiave di tutto si chiama CTRL+SHIFT+B. Per i due che non sanno di 
cosa parlo, questa è la combinazione di tasti che compila la solution. Tutta la 
tecnica, che nel titolo ho sintetizzato con un pomposo Error Driven 
Refactoring, si basa sul provocare errori di compilazione. Facciamo qualche 
esempio:
Cambiare il nome ad una variabile, ad un tipo, oppure a un 
metodo, è il caso più banale. Si va sul membro che si desidera cambiare, lo si 
cambia e si compila. A questo punto, nel Task Panel si presenteranno un certo 
numero di errori, talvolta qualche centinaio. Non sempre serve risolverli tutti, 
perchè se avete mai fatto caso il compilatore più di qualche volta genera due o 
tre avvisi per lo stesso errore. La mia tecnica prevede di risolvere al 
massimo la prima decina e poi ricompilare. E avanti così finche il codice non da 
più errori. Sembra una attività ingrata, ma una volta che si è presa confidenza 
è più veloce di quello che si possa immaginare. Non è detto che a questo punto 
il codice compilato funzioni. Ad esempio se usate la reflection per istanziare 
un tipo è probabile che in fase di compilazione non ci sia alcun errore, mentre 
quando lo eseguite ovviamente solleva una eccezione. Una bella ricerca testuale 
non guasta.
Cambiare la firma di un metodo è un'altra cosa abbastanza 
facile. Analogamente al caso precedente si provoca l'errore cambiando la firma. 
Talvolta conviene dapprima cambiare il nome del metodo e completare il primo 
passaggio. Poi si cambierà il tipo di ritorno oppure i parametri e si procede 
nuovamente alla compilazione. In questi casi occorre avere la cautela di 
accorgersi quando si cambia il tipo di un parametro con uno che sia compatibile, 
ad esempio con una classe padre. Il compilatore in questi casi non ci viene in 
aiuto, ma se contestualmente create una errore fittizio inserendo un carattere 
estraneo nel nome del metodo è più facile che si ritrovino tutte le chiamate. 
Inoltre bisognerà avere la cautela di capire che cosa succede nel corpo del 
metodo. Anche qui un carattere estraneo nel nome del parametro che occorre 
modificare aiuterà a trovare tutti gli usi che sono stati fatti e a verificare 
che non vi siano anche errori logici oltre che sintattici. In questo caso non 
occorre nemmeno ricompilare perchè sarà l'intellisense a indicarci l'errore con 
una simpatica sottolineatura.
Accomunare alcune classi con un'unica classe padre. 
Tipicamente in questi casi, si parte dapprima con la realizzazione della classe 
base vuota e immediatamente la si sostituisce a object nelle classi che dovranno 
estenderla. Nessun errore dovrebbe presentarsi. Però se si accomunano pià classi 
significa che si intende spostare uno o più metodi e proprietà ad un livello più 
basso. Perciò mano amano si fà cut & paste e si trasportano tali metodi 
nella nuova classe. Ad ogni spostamento si compila e così si individuano ad 
esempio i membri privati che sono referenziati da tali metodi e si trasportano 
anch'essi. In breve la classe dovrebbe cominciare ad indicare che alcuni metodi 
sono sovrascritti e che occorre l'uso dell'operatore new. Questi sono i metodi 
che sono rimasti nelle altre classi e vanno del tutto cancellati assieme ai 
membri privati che sono i più difficili da scovare, perchè non danno errore. Ad 
accomunare spesso è un'interfaccia o una classe astratta. Ne pimo case non c'è 
alcun problema perchè quando l'interfaccia è finita la si fa implementare alle 
classi e nel digitare Visual Studio autonomamente creerà i metodi e ad 
accorgersi se esistono già. Con le classi astratte è un po' più complesso. Si 
aggiungono i metodi astrtti e quindi si dovranno aggiungere gli override dove 
mancano oppure creare i metodi vuoi facendosi aiutare dagli errori e 
dall'intellisense. 
Estrapolare delle classi da un progetto per crearne uno 
nuovo. Questa è la forma di refactoring che mi piace di più. Occorre tenere 
presente sempre che alcune classi possono essere usate da altri assembly, e che 
talvolta il codice che si scrive diventa un buon candidato al riutilizzo. Perciò 
trasportarlo in un altro assembly è vitale. Quindi si crea il nuovo progetto. Io 
ho l'abitudine di dare al progetto il medesimo nome del namespace che contiene. 
Questo è di enorme aiuto ad orientarsi nel trovare quello che si cerca. Tornando 
al problema a questo punto usando il Drag & Drop si trascinano le classi da 
un progetto all'altro e contestualmente si aggiunge la nuova reference. I 
progetto dovrebbe compilare immediatamente perchè nelle classi spostate è 
rimasto il namespace originale. Quindi occorre un bel replace. Si evidenzia il 
namespace da cambiare e si premo CTRL+H. Quindi ci si assicura di avere lo scope 
di progetto e si sostituisce con il namespace nuovo. Finalmente il compilatore 
comincia a dare errori. Questi potranno essere causati dalla mancanza di una 
reference oppure da uno using sbagliato. Non resta che aggiungere quello che 
serve e la solution tornerà a ricompilare.
Quelli che ho indicato sono solo alcuni dei casi da gestire. Indicarli tutti 
mi sembrava improponibile. Quello che mi interessa far capire è che non serve 
avere dei tool molto evoluti per potersi dedicare alla tecnica del refactoring. 
A mio parere nessun tool potrà mai arrivare a fare tutto ciò che ci serve, ma 
con un po' di fantasia si arriva a trovare una soluzione efficace.
Ora non avete più scuse. Refactor your life.
powered by IMHO