2010-05-28 11 views
8

Ho avuto la mia parte di progetti in cui la prima cosa che penso è: "Questo codice fa schifo, riscriviamolo nel quadro X". Tutti sentono l'impulso ad un certo punto. In effetti, penso di aver avuto la voglia di riscrivere praticamente ogni progetto in cui sia mai stato.Quando cedere e iniziare The Big Rewrite?

Tuttavia, è opinione comune che una riscrittura totale sia generalmente una cattiva idea. La domanda è: quando guardi un progetto e dici: "OK, è il momento di ricominciare".

Che tipo di metriche o esempi si può citare di dove era una riscrittura veramente necessario? Quanto male deve essere il codice? Quanti anni può avere un progetto prima di aver investito troppo?

+2

Età. Quando una tecnologia ha visto giorni migliori * e * il supporto per esso, in termini di programmatori, si sta assottigliando, è probabilmente il momento di scrivere qualcosa di nuovo. Ho riscritto i sistemi COBOL, DataFlex e VB6. Si può sostenere che il supporto per questi sistemi è ancora disponibile, ma la maggior parte dei programmatori vuole commercializzarsi con le ultime competenze, lasciando quindi le vecchie tecnologie nella polvere. Quindi, se hai problemi a trovare un programmatore DataFlex, allora sì, è probabilmente il momento di riscrivere. –

+0

Che ne dici di questo: cosa succede se hai creato un nuovo prodotto basato su ciò che hai appreso dal vecchio progetto che le persone vogliono riscrivere? Lasciare il vecchio e non considerare il nuovo progetto parte della stessa linea? –

risposta

11

Sono d'accordo con Joel, si dovrebbe solo riscrivere il software come ultima risorsa.

http://www.joelonsoftware.com/articles/fog0000000069.html

Il problema è che tutti pensano ad un certo punto nel tempo, che sarà più facile di riscrivere qualcosa da zero, quando in realtà non lo è. Quel codice che ha avuto un certo numero di aggiornamenti nel tempo, funziona in un certo modo per un motivo. Di solito ci sono un sacco di piccoli elementi logici che sono fatti in un certo modo, a causa di un aggiornamento o una correzione di un bug ecc. Quando riscrivi qualcosa, devi imitare il comportamento di ciascuna di quelle correzioni, perché sono importanti per una ragione oppure un'altra.

Sentirai molto sull'analisi dei costi e quando è opportuno riscrivere, il problema è che spesso l'analisi è sbagliata. Se ci vuole un giorno per fare un semplice aggiornamento, è ancora molto meno dei potenziali mesi che probabilmente serviranno per analizzare, progettare, codificare, testare e implementare la nuova versione.

Il mio vecchio capo e io scherzavamo su questo programma di sistema di raccolta dell'attività commerciale utilizzata. Era orribile, odiavamo mantenerlo. Un giorno fece il commento e aveva assolutamente ragione: "Sai quanto odiamo questo sistema, funziona, fa quello che serve". Siamo entrambi d'accordo sul fatto che, per quanto abbia succhiato, ha funzionato, e alla fine non l'abbiamo riscritto e salvato la società con centinaia di migliaia di dollari nella costruzione di un nuovo sistema. Pensando a quel sistema, non avremmo mai scoperto tutti i piccoli dettagli. Il codice era estremamente difficile da capire, che in definitiva è il motivo per cui abbiamo voluto riscriverlo in primo luogo.

+0

Esempio di conteggio secondario principale: Netscape. La riscrittura ha ucciso la compagnia. – Joel

+0

+1. Vero in molti casi. A volte il codice è mal progettato. Ho lavorato su un formato di file legacy in cui il programmatore originale non creava in alcun modo l'estensione del formato. Quindi lo ha esteso usando i bit di riserva in alcuni campi per indicare che era stato aggiunto un campo aggiuntivo, ma di nuovo non ha pensato all'estensibilità. È diventato impossibile aggiungere nuove informazioni al formato e "l'ultima risorsa": il formato doveva essere ridisegnato al costo di * settimane * di lavoro convertendo i vecchi dati. Dovrebbe essere stato riscritto la prima volta che sono state aggiunte estensioni, il che sarebbe costato solo poche ore di lavoro. –

7

Non riscrivere mai il software. Refactator per tutta la sua durata.

2

In genere, quel punto si ha quando l'analisi costi/benefici mostra che una riscrittura totale sta per risparmiare più del mantenimento del vecchio sistema.

Diversi fattori possono influenzare tale analisi (come piattaforme non più supportate, sviluppatori di talento difficili da trovare, ecc.).

Se si esegue l'Analisi costi/benefici nel modo giusto, si vedrà che non è mai redditizio eseguire una riscrittura completa. Ti costerà solo tempo e mal di testa.

6

Rewrite solo quando una delle due cose è vera:

  1. Il programma esistente non funziona in ogni caso, e non è neanche lontanamente di lavoro. (In altre parole, hai ereditato un codice basato sul "90%" dai tuoi predecessori, non un prodotto reale.)

  2. Il re-factoring passo-passo è impossibile perché il nuovo programma ha bisogno di un'architettura fondamentalmente diversa, deve essere eseguito su un diverso stack tecnologico o altro.

In altre parole, la linea guida (ci sono eccezioni, ma sono rari, non sarà probabilmente andare storto seguendo questa linea guida) è, riscrivere solo quando step-by-step ri-factoring da un il prodotto funzionante non è un'opzione.

1

Si consiglia di esaminare lo sviluppo iterativo. All'inizio, io e probabilmente quasi tutti gli sviluppatori "senior" si lamentano quando ne leggiamo. Nessuna pianificazione in avanti? Nessun pensiero in abstract e generalità? Basta fare? Non produce codice cattivo? Non proprio. Produrrà esattamente ciò di cui hai bisogno e mentre ritorni a guardare una funzione che è stata progettata per fare una cosa a cui ti rifatti di fare di più, così avanti e così via.

Questa è effettivamente una riscrittura costante ma non reale. Quelle funzioni che non vengono mai rifattorizzate vengono eseguite molto rapidamente e fanno esattamente quello che dovrebbero fare. Sei riuscito anche a implementarlo in una frazione del tempo perché non stavi pensando a 10 passi avanti e lo hai reso generico.

È possibile iniziare a leggere su di esso qui: http://www.extremeprogramming.org/rules/iterative.html

Per rispondere alla tua domanda direttamente, atteniamo al principio di "Se non è rotto non aggiustarlo". A meno che non ci sia bisogno oltre "dio che è brutto, voglio ripulirlo" non riscrivere quello che hai fatto.

1

Se è così male che ha bisogno di una riscrittura .... chiamatelo sostituzione. Aggiungi alcune nuove funzionalità, facilita la manutenzione e l'utilizzo. Sviluppalo con le ultime tecnologie disponibili per la tua azienda.

I più alti alti si sentono non c'è più valore in sostituzione di qualcosa che è a malapena a lavorare con qualcosa di nuovo & migliorata se migliorerà il flusso di lavoro & produttività.

Assicurati di non chiamarlo una riscrittura del codice crap, perché le persone che lo hanno scritto potrebbero ancora essere lì.

0

Se è già in una lingua moderna, refactoring invece di riscrivere.

Se avessi una app Cobol e il mio mainframe se ne andasse alla fine, è ora di riscriverlo. Se ho trovato una vecchia app scritta in FoxPro e abbiamo ancora bisogno della funzionalità, riscrivi.

Ma se è in Java, non importa quanto sia grave, refactoring un bit alla volta. Farò davvero meno male.

1

Se il codice soddisfa assolutamente zero dei requisiti per il progetto, potrebbe essere un buon momento per riscriverlo.

1

Una delle poche situazioni in cui una riscrittura può essere necessaria è quando il linguaggio è diventato obsoleto e non sono disponibili sviluppatori per mantenerlo. In questo caso potresti dover riscrivere anche un buon codice che funzioni perfettamente.

E aggiungendo la beffa al danno, si può facilmente finire con qualcosa di peggio di quello che hai iniziato.

1

Una "riscrittura" (o almeno una parte seria di refactoring) è a volte il modo migliore per realizzare un soluton non è scalabile.

Un esempio di questo è un pacchetto di pittura che scrivo negli anni '80. È stato un po 'divertente lavorare su una bitmap a 16 colori. Quando era 20kB di codice BASIC, ho pensato "dovrei riscrivere questo per renderlo capace di gestire 16 o 256 immagini a colori". Ma era "troppo lavoro". Quando era 50kB era chiaro che aveva davvero bisogno di essere riscritto, ma ci sarebbe voluto troppo tempo. Così ho continuato aggiungendo il codice che si basava sul fatto che fosse un'immagine a 16 colori, fino a raggiungere il punto in cui era di 140kB e assolutamente non pratico da riscrivere. Mi sono sempre pentito di non aver morso il proiettile quando la riscrittura era a poche ore di lavoro.

Un altro esempio: ho lavorato a un pacchetto di grafica vettoriale che trasmetteva eventi attorno a tutti gli oggetti nella sua gerarchia scenegrafica. Nelle fasi iniziali aveva poche decine di oggetti e, come disse il mio manager, "possiamo trasmettere a oltre 10.000 oggetti al secondo", quindi le trasmissioni continuarono. Ho suggerito di fare in modo che gli oggetti interessati sottoscrivano gli eventi di cui avevano bisogno per rimuovere l'inefficienza, ma non c'era "nessun bisogno". Dopo 2 anni (40 anni di sforzi), il programma si fermava per 2-4 secondi alla volta perché lo scenegraph conteneva più di 500 oggetti e i 2 eventi di trasmissione erano saliti a 40 circa.

Questo schema è stato ripetuto in diversi progetti in cui sono stato coinvolto nel corso degli anni: si riscontra un grave difetto di progettazione o un debito tecnico e si rinvia fissandolo perché (a) non è un problema "ancora", e (b) costerebbe troppo tempo per risolverlo ora. Col passare del tempo, diventa linearmente più un problema, ma esponenzialmente più costoso da risolvere. Quindi, anche se è necessario sistemare sempre di più, è più difficile giustificare il costo di fissarlo.

In questi casi, il problema tecnico o l'errore di progettazione deve essere risolto come all'inizio di come possibile. Ci vuole coraggio (se sei un manager) o persuasività (se sei un sottotenente) per trattenere il tuo programma per una settimana, ma immagina di non aver ricorso, ma di dedicare 2 mesi alla correzione tra un anno!

Ovviamente, questo argomento non si applica a tutti i casi. È necessario valutare il rapporto costi/benefici di qualsiasi soluzione proposta e considerare la scalabilità del problema: se il problema è una costante, è possibile correggerlo per lo stesso costo in qualsiasi momento in futuro. Se ogni nuova classe che aggiungi al tuo sistema combina il difetto e prevedi di aggiungere hundres di nuove classi, torna indietro e aggiustalo ora.

1

Uno dei grandi argomenti di propaganda sulla programmazione è che deve essere progettato per il codice e/o il riutilizzo basato su moduli. In altre parole, la funzionalità dovrebbe essere suddivisa in parti discrete riutilizzabili. Se si dispone di codice che sta effettivamente facendo qualcosa, e che soddisfa un requisito, l'argomento non è quindi che il codice deve essere riscritto, ma piuttosto deve essere refactored ad uno stato in cui può essere riutilizzato.

Questo non significa che non si debbano gettare grandi pezzi di codice e rimpiazzarli .. In effetti, l'idea del refactoring ci dice di fare esattamente questo. Tuttavia, l'idea è che mentre lo facciamo, dovremmo testare e migliorare per garantire un comportamento compatibile e una maggiore riutilizzabilità e modularizzazione.

Infatti, se si può prendere anche solo un modulo che fa qualcosa per soddisfare un requisito, e rielaborarlo per essere riutilizzabile in "versione 2", quindi per definizione non si è buttato fuori il codice base e si è iniziato al di sopra di. E perché vorresti se anche nel codice sbagliato, di solito sono necessari solo alcuni accorgimenti per ripulirlo in un buon codice? Per non parlare delle perle di codice decente o addirittura "buono" che esiste nel progetto.

0

La ragione per cui si prevede di riscriverlo è perché, i problemi che si stanno vedendo ora non erano previdenti quando è stato scritto, potrebbero esserci due ragioni per questo 1. Non è stato pensato per fare ciò che è facendo ora o 2.Era semplicemente un errore.

Dagli un pensiero molto completo, se sei in grado di prevedere tutte le cose che potrebbe richiedere.

Solo dopo riscriverlo. Ma in genere il codice più ben scritto e ben gestito richiede solo il refactoring.

Cheers, Pavan

1

Disclaimer: io lavoro in un'università, in cui lo scopo del software è quello di stabilire o confutare la validità di nuove idee. Mentre alcuni accademici hanno mantenuto lo stesso software per oltre 20 anni (esempi: lo Glasgow Haskell Compiler e lo ACL2 theorem prover, molti accademici abbandonano vecchi progetti e avviano nuovi progetti periodicamente.Per molti di noi, la corretta regola empirica è purché software rimane produttiva, mantenere e migliorare il refactoring — non ricominciare da capo "produttivo" significa cose diverse in contesti diversi, ma alcuni esempi includono:.

  • Sei ancora la scrittura di documenti sul software
  • dottorandi stanno ancora utilizzando il software come infrastruttura per provare nuove idee
  • aver stabilito una popolazione significativa di utenti, e non si vuole lasciarli a bocca asciutta

Per noi, una riscrittura completa può essere giustificato se offre la possibilità di sperimentare nuove idee . Una mossa rischiosa per una completa riscrittura è cercare di avere un impatto maggiore. Ad esempio, stiamo riscrivendo un ottimizzatore in Haskell (è stato scritto in Objective Caml) perché scrivendolo in Haskell possiamo ottenere più persone per usarlo, e possiamo stabilire la sua credibilità usandolo in un grande sforzo open source. Ma è ancora una mossa rischiosa per noi, perché è difficile pubblicare articoli su vecchie idee riscritte in nuove implementazioni.

La versione breve è quella una riscrittura completa non è quasi mai giustificata.