2009-03-05 14 views
10

Supponiamo che tu abbia un programma che attualmente funziona come dovrebbe. L'applicazione ha un codice molto scarso dietro di esso, consuma molta memoria, non è scalabile e richiederebbe una grande riscrittura per implementare qualsiasi cambiamento di funzionalità.A che punto il refactoring non vale la pena?

A che punto il refactoring diventa meno logico di una ricostruzione totale?

risposta

10

Joel ha scritto un bel saggio su questo argomento:

Things You Should Never Do, Part 1

La lezione chiave che ho avuto da questo è che, anche se il vecchio codice è orribile, fa male i tuoi occhi e il tuo senso estetico, c'è una bella buone probabilità che un sacco di quel codice stia correggendo errori e problemi non documentati. Vale a dire, ha un sacco di conoscenza del dominio incorporato in esso e sarà difficile o impossibile per voi replicarlo. Colpirai costantemente contro i bug-of-omission.

Un libro che ho trovato immensamente utile è Working Effectively With Legacy Code di Michael C. Feathers. Offre strategie e metodi per approcciare anche il codice legacy davvero brutto.

+0

Fred Brooks ha detto di "costruirne uno da buttare", ma non stava utilizzando tecniche agili e qualsiasi funzionalità aggiunta veniva documentata e compresa e quindi era possibile riscriverla senza perdita. – 13ren

+0

Senza contare che ci sono SEMPRE molti più dettagli che è necessario implementare a cui non hai pensato quando hai delineato il grande progetto. –

0

Quando si impiegano più tempo per il refactoring rispetto alla scrittura del codice.

0

Un'opzione sarebbe quella di scrivere test di unità per coprire l'applicazione esistente e quindi iniziare a refactarlo a poco a poco, utilizzando i test di unità per assicurarsi che tutto funzioni come prima.

In un mondo ideale che ci si dispone già di unit test per il programma, ma dato i tuoi commenti circa la qualità delle app Sto indovinando non lo fai ...

1

Nel punto in cui il software non fa quello che dovrebbe fare. Refactoring (cambiare il codice senza modificare la funzionalità) ha senso se e solo se la funzionalità è "come previsto".

3

Bene, la risposta più semplice è se ci vorrà più tempo per il refattore che per ricostruire, quindi dovresti semplicemente ricostruire.

Se si tratta di un progetto personale, si consiglia di ricostruirlo in ogni caso, poiché probabilmente si imparerà di più da una ricostruzione ex-novo che da un refactoring, e questo è uno dei principali obiettivi dei progetti personali.

Tuttavia, in un ambiente limitato nel tempo professionale, si dovrebbe sempre andare con quello che costa alla società la minor quantità di denaro (per lo stesso guadagno) nel lungo periodo, il che significa scegliere quello che richiede meno tempo.

Naturalmente, può essere un po 'più complicato di così. Se altre persone possono lavorare sulle funzionalità mentre viene eseguito il refactoring, allora potrebbe essere una scelta migliore rispetto alla necessità di aspettare che venga creata una versione completamente nuova. In tal caso, la ricostruzione potrebbe richiedere meno tempo rispetto a a, ma il processo di refactoring sarebbe stato necessario, ma è necessario prendere in considerazione l'intero progetto e tutti i contributori del progetto.

1

Ho lavorato con tali applicazioni in passato. L'approccio migliore che ho trovato è graduale: quando lavori sul codice, trova le cose che vengono eseguite più volte, raggruppale in funzioni. Tieni un taccuino (lo sai, vero, con la carta e una matita o una penna) in modo da poter contrassegnare i tuoi progressi. Usalo in combinazione con il tuo VCS, non al posto di esso. Il notebook può essere usato per fornire una panoramica delle nuove funzioni che hai creato come parte del refactoring, e il VCS ovviamente riempie gli spazi vuoti per i dettagli.

Nel corso del tempo, si sarà consolidato molto codice in luoghi più appropriati. La duplicazione del codice durante questo periodo di tempo sarà quasi impossibile, quindi procedi nel modo migliore possibile finché non raggiungi un punto in cui è possibile davvero avviare il processo di refactoring, controllare l'intero codice base e lavorare su nel suo insieme.

Se non hai abbastanza tempo per quel processo (che richiederà molto tempo), riscrivere da zero utilizzando un approccio di prova è probabilmente meglio.

1

Se ci si può permettere il tempo per ricostruire completamente l'app, non è necessario migliorare la funzionalità in modo incrementale e non si desidera conservare alcun codice esistente, quindi la riscrittura è sicuramente un'alternativa valida. È possibile, d'altra parte, utilizzare il refactoring per eseguire una riscrittura incrementale sostituendo lentamente le funzioni esistenti con funzioni equivalenti meglio scritte e più efficienti.

6

Uno dei vantaggi del refactoring rispetto alla ricostruzione è che, se è possibile eseguire il refactoring passo dopo passo, ad esempio in incrementi, è possibile verificare gli incrementi nel contesto dell'intero sistema, rendendo più veloce lo sviluppo e il debug.

Il codice vecchio e distribuito, anche se brutto e lento, ha il vantaggio di essere stato testato a fondo e questo vantaggio si perde se si parte da zero.

Un approccio di refactoring incrementale ha anche contribuito a garantire che sia sempre disponibile un prodotto che può essere spedito (e sta migliorando costantemente).

C'è un bel articolo sul web su how Netscape 6 was written from scratch and it was business-wise a bad idea.

1

Se l'applicazione è molto piccola, è possibile riscriverla da zero. Se l'applicazione è grande, non farlo mai. Riscrivialo progressivamente, un passo alla volta confermando che non hai infranto nulla.

L'applicazione è la specifica. Se lo riscrivi da zero, molto probabilmente incontrerai un sacco di insidiosi bug perché "nessuno sapeva che la chiamata a questa funzione avrebbe dovuto restituire 3 in quel caso molto specifico" (comportamento non documentato ...).

È sempre più divertente riscrivere da zero in modo che il tuo cervello possa indurti a pensare che sia la scelta giusta. Stai attento, probabilmente no.

0

Nessun documento, nessun writer originale, nessun test case e un mucchio di bug rimanenti.

1

Uncle Bob weighs in con il seguente:

Quando è una riprogettazione la strategia giusta?

Sono contento che tu abbia fatto quella domanda. Ecco la risposta. Mai.

Guarda, hai fatto il casino, ora ripulisci.

0

Non ho avuto molta fortuna con piccole modifiche incrementali quando il codice che eredito è davvero pessimo. In teoria, il piccolo approccio incrementale suona bene, ma in pratica tutto ciò che finisce è una migliore, ma ancora mal progettata applicazione che tutti pensano sia il VOSTRO design. Quando le cose si rompono, le persone non pensano più che sia dovuto al codice precedente, ora diventa TUA colpa. Quindi, non utilizzerei la parola riprogettazione, refactoring o qualsiasi altra cosa che implichi un tipo di gestore che stai cambiando le cose a modo tuo a meno che non stavo davvero andando a farlo a modo mio. Altrimenti, anche se potresti aver risolto dozzine di problemi, tutti i problemi che ancora esistevano (ma non sono stati scoperti) saranno ora attribuiti alla tua rielaborazione. E ti assicuriamo che se il codice è cattivo, le tue correzioni scopriranno molti più bug che sono stati semplicemente ignorati prima perché il codice era così brutto per cominciare.

Se davvero sai come sviluppare sistemi software, farei una riprogettazione dell'intero sistema. Se non sai DAVVERO come progettare un buon software, allora direi di attenermi alle piccole modifiche incrementali, altrimenti potresti finire con un codice base altrettanto cattivo dell'originale.

Un errore che si verifica spesso durante la riprogettazione è che le persone ignorano il codice originale. Tuttavia, la riprogettazione non deve significare totalmente ignorare il vecchio codice. Il vecchio codice doveva ancora fare ciò che il tuo nuovo codice deve fare, quindi in molti casi i passaggi necessari sono già nel vecchio codice. Copia e incolla, quindi modificare funziona a meraviglia quando ridisegnare i sistemi. Ho scoperto che in molti casi, la riprogettazione e riscrittura di un'applicazione e il furto di snippet dal codice originale sono molto più veloci e molto più affidabili di piccole modifiche incrementali.