2011-12-19 2 views
7

L'avete già sentito, l'applicazione Delphi classica.Piano di refactoring per 17+ anni di codice Delphi non verificabile

Con le librerie 3a parte siamo a 1,5 milioni di linee di codice, probabilmente 200.000 della nostra (Dev Express, NexusDB, etc etc)

Uno datamodule enorme che ho lentamente suddivisione in 5 (e probabilmente bisogno di più). Spostare alcune logiche di business su questi datamodules lentamente ma sicuramente come metodi del modulo.

Tutto codificato 'sotto il pulsante', nessuna classe nostra. Alcune forme hanno 20k linee di codice.

Ho bisogno di un piano ragionevole per ottenere questo in un posto migliore. In questo momento non si può davvero provare qualsiasi di esso, piccoli cambiamenti potrebbero introdurre un esercito di insetti, ecc

stavo pensando, per iniziare, ottenere un'unità in corso per ogni forma principale ed estrarre la logica di business in forma di questa classe/unità. Qualcosa come TMyForm ha un TMyFormClass.pas in modo che TmyForm finisca con nient'altro che l'interfaccia utente. Continuare a modulare i datamodule, scrivere test al più presto. Solo refactoring su cui stiamo lavorando.

suono sano di mente, suggerimenti aggiunta, qualcuno vi prego di inviarmi liqour ....

+10

Acquista liquore, bevi alcolici, dimenticati del codice –

+3

Più seriamente, quali sono i tuoi obiettivi? Cosa ti ha spinto a voler cambiare rotta dopo 17 anni? Quali benefici speri di ottenere dal refactoring? Rispondere a queste domande dovrebbe guidarti nella strategia generale. Cerca di ottenere il meglio per il tuo dollaro. Solo refactoring per guadagni tangibili. –

+2

Sii più commerciale a riguardo: chiedi quanti liquori il tuo capo/cliente è disposto a comprare per ripulirlo? :-) –

risposta

5

Alla fine, questa è una decisione aziendale e dovrebbe essere presentata come tale. Cosa darebbe più valore alla tua azienda. Identificalo e ricollegalo per prima, dove puoi dimostrare (dimostrare) che i benefici per il business sono almeno alti, se non il valore più alto possibile.

Credo che qualsiasi piano che inizi con un'idea di implementazione (regole MVC! Dividi tutte le cose!) Senza una valutazione del valore aziendale, sarà uno sforzo ampiamente sprecato.

Esempio: la mia applicazione stampa e mi aiuta a spedire le fatture ai miei clienti. L'area più preziosa dell'applicazione per il refactoring è che non sono mai stato in grado di gestire la priorità del cliente e fare in modo che il batch funzioni correttamente. Questo miglioramento ha un chiaro valore aziendale e il refactoring mi richiederà (stimare) 10 giorni. Durante questo periodo, spero anche di disaccoppiare il mio codice di accesso al database, dalle mie regole aziendali, e disaccoppiare le mie regole di business dall'interfaccia utente, per solo l'area del codice che ha a che fare con gli elementi Priorità della mia interfaccia utente , il che significa che tocca lo solo il 10% del mio codice UI, e questo sforzo di refactoring mi porta (stimino) altri 10 giorni. Ciò significa un totale di 20 giorni di sforzo e il codice sarà in grado di fare qualcosa di nuovo. Intendo anche fare alcuni test unitari (il mio primo in assoluto) che si baseranno sulla capacità di deridere il mio livello di database.

3

ho avuto questa volta (600kline serverapp costruito utilizzando un pacchetto designtime per le richieste del HTML è sceso in grembo), e ho iniziato cercando di ridurre il numero di linee identificando codici simili e estraendoli a classi semplici solo per ridurre il volume. Riduzione copia e incolla per così dire.

Alcuni moduli/moduli creati da programmatori successivi erano del tipo stringlytyped. Ripulire questo problema è stato anche uno dei primi passi.

Fare tutto ciò mi ha aiutato anche a conoscere l'applicazione e iniziare a pensare a una nuova struttura. Ho prima fatto un giro limitando l'accesso a/eliminando le variabili globali.

I passaggi sopra descritti sono stati per lo più eseguiti in parallelo.

Successivamente ho iniziato a ripulire alcuni moduli secondari relativi in ​​primo luogo per averne un'idea, per poi passare a quelli più importanti. L'applicazione ha funzionato per la maggior parte di questo tempo, con solo una settimana occasionale che il codebase non era in uno stato lavorabile.

Il motivo principale della pulizia era che l'app utilizzava funzionalità legacy del pacchetto del componente principale che era stato rimosso da una versione più recente. .. che a sua volta aveva nuove funzionalità che erano necessarie :-)

In generale sono più adatto all'approccio evolutivo in questi casi. Le riscritture massicce e le rearchitectures sono sempre nel tempo.

+0

+1 per approccio evolutivo. –

+1

Probabilmente sarà la mia risposta. Principalmente cercando di scoprire alcune buone pratiche, ecc ... una business class per andare con una forma un passo decente vs cercando di scrivere un quadro ORM e MVP (che dubito di fare su questo progetto). –

+1

Se inizi a creare qualcosa chiamato "FooBusinessClass' da un modulo chiamato" FooForm', e alla fine, tutto è ancora accoppiato a tutto, non hai guadagnato quasi nulla. Se disaccoppia la metà dell'applicazione dall'altra metà, hai fatto un grande salto. –

3

Aggiunta di funzioni? Tratta il codice legacy come una libreria di terze parti e scrivici sopra un livello, quindi tieni il codice separato.

Fissaggio o modifica? Scopri il modo più semplice per testare. Una mescolanza di test di unità e di mano, forse simulando qualche livello di servizio.

Ripulire le parti del codice che si visitano frequentemente. Non passare molto tempo con le parti che non usi mai. Nel corso del tempo un'architettura ideale diventerà chiara man mano che inizi ad evolvere verso di essa. Pianifica solo quando è necessario.

+1

Il risultato netto dell'approccio "strato" è una malattia mentale persistente e incurabile. Non consigliato. Quando perdi la possibilità di cambiare il tuo codice esistente, stai andando verso una strada senza uscita. Lo chiamo "codice lasagna", un parente di "spaghetti code" ma con strati invece di insidiosi fili a righe. –

+0

Concordo, i livelli aggiungono complessità e indirezione che è meglio evitare. Tuttavia, quando si tratta di una base enorme e fragile di codice legacy, a volte l'aggiunta di un livello è la decisione più pragmatica. Puoi sempre raggiungere il livello sottostante quando le tue astrazioni si perdono. –

2

Innanzitutto proverei a saperne di più su come funziona il codice.

Per fare ciò, procurarsi una copia delle librerie di registrazione SmartInspect o CodeSite e registrare la voce e l'uscita di ogni singolo metodo nell'applicazione (SmartInspect ha una procedura guidata per farlo automaticamente). Per completare l'immagine, è necessario aggiungere gestori di eventi per ogni evento TDataSet.AfterScroll e TDataSet.AfterOpen nel proprio datamodule e registrare la voce/uscita anche di quelli.

Avanti tu o uno dei tuoi migliori utenti è necessario eseguire il programma e provare ad esercitare ogni singolo bit di funzionalità in esso. Mentre lo fai, genererai log di traccia che ti dicono esattamente quali metodi e componenti del database sono usati da ogni modulo e dai suoi componenti. Fatelo in modo pianificato e strutturato in modo che i vostri log di traccia non siano un vero disastro.

Avanti attacco che mostro modulo dati. Suppongo che tu stia utilizzando i componenti dataaware sui tuoi moduli, se non vedi this answer dei miei.

Sono d'accordo sul fatto che dovresti usare più datamodule invece di crearli da zero il mio consiglio è di crearli copiando e rinominando il mostro di dati. Piuttosto che aggiungere componenti e codice a loro, si eliminano componenti e codice una volta che si è certi che non è richiesto dai moduli che fornisce.

La ragione per cui consiglio di farlo è che rende molto facili i confronti tra i nuovi datamoduli e il datamodule mostro che utilizza Beyond Compare o qualcosa di simile. Se qualcosa non funziona correttamente nel tuo nuovo datamodule, caricalo in BC contro il mostro originale e sarai in grado di vedere facilmente quale valore di proprietà l'IDE ha ingoiato o quale linea cruciale hai eliminato accidentalmente.

+0

BeyondCompare e qualsiasi altro strumento di diffusione ti affogheranno rapidamente nel rumore, una volta avviato il refactoring. Trovare una linea che sia stata "refactored in nowhere" non diventerà più facile se hai uno strumento diff o meno. –

+0

Ovviamente usiamo BC in modi diversi in quanto trovo uno strumento diff inestimabile in circostanze come queste. :-) – LachlanG

Problemi correlati