2010-10-19 5 views
14

Mi è stato assegnato un lavoro su un enorme progetto Java e l'influenza di numerose iterazioni di sviluppatori è evidente. Non esiste uno stile di codifica standard, una formattazione, convenzioni di denominazione o struttura di classe. È un buon giorno quando mi imbatto in una lezione con Javadoc, e il test unitario è un sogno ad occhi aperti felice.Pulizia di un grande progetto Java legacy

Finora quelli di noi sul progetto si sono "mescolati", adattandosi alle convenzioni esistenti di qualsiasi classe a cui stiamo lavorando, ma il tempo sta per imporre un po 'di ordine e coerenza.

È una sfida scoraggiante, e sto cercando qualsiasi consiglio che le persone potrebbero avere su tale compito. Ci sono delle strategie che sono state particolarmente efficaci o delle insidie ​​a cui prestare attenzione? È anche una buona idea provare?

Modifica da aggiungere: non voglio dare l'impressione che il progetto sia cattivo, in realtà è progettato in modo solido e in gran parte ben scritto. Sta solo sentendo la sua età e l'inevitabilità della manutenzione ...

+0

Immagino che dovresti leggere alcuni degli argomenti più aggiornati su [refactoring] (http://stackoverflow.com/questions/tagged/refactoring?page=1&sort=votes) e [legacy] (http: // stackoverflow. com/domande/tag/legacy? sort = voto). –

risposta

11

Trovo che Eclipse sia uno strumento incredibilmente potente per operazioni come questa.

Un sacco di persone giuro per strumenti da riga di comando e editor di testo modali-based per la programmazione, ma ci sono forti vantaggi di usare un IDE completo per importante refactoring:

  • automatica, in tempo reale, la compilazione mostra gli errori mentre accadono e ovunque accadano. Solo perché apporti una modifica e nulla nella classe o interruzioni di pacchetto immediate non significa che non hai creato problemi altrove. Le bandiere rosse saliranno nell'albero dei pacchetti in eclissi e ti condurranno direttamente a loro.
  • Rinominazione basata su tabella e in movimento. Rinominare elementi del tuo codice può avere un impatto molto più grande di quello che sai. Eclipse mostrerà i dettagli di ogni istanza dell'elemento in questione e il modo in cui verrà modificata dal nome.
  • La gestione automatica delle importazioni consente di risolvere il problema garantendo che tutte le importazioni siano in ordine. Eclipse aggiungerà automaticamente le importazioni mentre vengono utilizzate e contrassegnerà quelle non utilizzate con le lampadine di azione per la rimozione con un clic.
  • Utilizzare gli stili di codice per garantire che tutti i file di origine utilizzino lo stesso formato per tutto. Spazi, rientri, nuove linee, parentesi possono essere tutti formattati per te. Funziona come si crea nuovo codice e per l'aggiornamento dei file esistenti.

Oltre al set di strumenti di Eclipse, è possibile utilizzare altri strumenti Java moderni per garantire che il codice funzioni sempre.

  • Le suite di test consentono di garantire costantemente che le modifiche apportate non influiscano negativamente sulla funzione del progetto. Se si intende eseguire il refactoring di una funzione, scrivere due o tre test case che dimostrino il modo in cui funziona. Assicurati che corrano prima e dopo eventuali modifiche. Questo è il modo più semplice per individuare i problemi prima che diventino un problema.
  • Utilizzare uno strumento come Maven per assistenza con dipendenze, test, compilazione e distribuzioni. Non perdere tempo a svolgere nuovamente i compiti sopra citati. Concentrati sulla scrittura del codice che fa il lavoro.

edit:

anche io personalmente preferisco Eclipse perché io sono quello che fa il refactoring, non qualche strumento automatico che non conosce quasi nulla circa il mio codice.

+0

Ottima risposta, vale anche la pena di lanciare il plugin Eclipse di FindBugs se si vogliono correggere molti bug/incongruenze durante il refactoring .... – mikera

6

È possibile utilizzare un tool per imporre un formato comune sul codice sorgente nel progetto. A parte questo, vedere Michael Feathers 'Lavorare in modo efficace con il codice legacy (dove "codice legacy" è definito come "codice senza test di unità"), che descrive come trasformare gradualmente il codice legacy in codice completamente testato e testabile.

1

Il mio suggerimento sarebbe aggiungere qualcosa come Checkstyle al tuo sistema di compilazione. È difficile convincere la direzione ad acquistare l'idea di fare una revisione completa tutto in una volta. Progetta ciò che pensi sia un buon insieme di linee guida di stile e implementale in Checkstyle e aggiungilo alla tua build.

Quindi, richiedere che tutto il nuovo check-in del codice non interrompa Checkstyle. Ciò significa che ogni volta che lavori su un corso, lo porti agli standard. Non sembrerà che tu stia facendo del lavoro extra se è solo un po 'di qualcosa che devi fare prima di impegnarti per un po'.

Inoltre, esistono plugin checkstyle per Eclipse.

0

È un compito piuttosto comune, non molto gioioso ma nemmeno un incubo ... Potrebbe essere peggio, se codificato in altri linguaggi (Perl, PHP, C++, -gasp- VB ...); in realtà, Java è uno dei migliori per il tuo scenario.

Ottieni un IDE decente (Eclipse) e passa un buon tempo a capire dipendenze e cicli di chiamata. Ci vorrà molto tempo per familiarizzare con tutto, quindi prova prima a fare solo piccole modifiche.

Quando manca la documentazione, l'IDE (e la compilazione statica) aiuta molto a sapere chi sta usando quale classe o metodo, e si può fare il refactoring con molta confidenza. Ma prima cerchiamo di identificare in quali livelli/pacchetti/classi viene utilizzata la riflessione (esplicitamente dal tuo codice, o implicitamente dai tuoi framework - ad esempio alcuni getter e setter).

Ci sono molti libri dedicati a "Reengineering Legacy Software" e problemi correlati.

3

Quello che mi piace fare in questa situazione è:

  1. In primo luogo convertire il progetto di utilizzare una build di Maven, in modo che io so quale versione le dipendenze sono.
  2. Questo mi dà anche alcuni rapporti sulla qualità del codice decenti da utilizzare come benchmark, inclusi checkstyle, findbugs, pmd e copertura del codice.
  3. E io (e molti altri) siamo abituati a questa struttura, quindi sappiamo dove trovare la fonte, i test unitari, le risorse ecc.
  4. Se si tratta di un progetto di grandi dimensioni, probabilmente un layout di progetto multi-modulo la struttura corretta da usare.
  5. Se al momento è un big-ball-of-mud, questo diventa il modulo principale che può essere successivamente refactored in moduli separati.
  6. Il standard maven directory structure fornisce il posto per, e quindi incoraggia i test unitari.
  7. I test di unità sono un prerequisito fondamentale prima che il refactoring possa iniziare.
  8. Stabilire un ciclo di integrazione di integrazione continua utilizzando Hudson.
+0

Praticamente lo stesso che sto facendo ora con il mio compito, eccetto i passaggi 2 e 8. – Ither

3

Iniziare con le classi monolitiche e scomporle (più di 500 istruzioni escludendo commenti e righe con solo parentesi). Introdurre interfacce, quindi iniezione di dipendenza.

0

Ho avuto una tale esperienza. Sono d'accordo con le persone che raccomandano build, eclipse, Checkstyle, refactoring di classi grandi ecc. Capisco che non è possibile ottenere una copertura completa prima di iniziare a lavorare. Io suggerirei 1. riformattare il codice in modalità batch usando il checkstyle o uno strumento simile 2. abilitare tutti gli avvisi ragionevoli in Eclipse e il codice refactoring che causa tali avvertimenti se questo refactoring è banale. In altri casi, metti @SupressWarning e TODO speciale per tornare a questo codice più tardi. 3. utilizzare test automatici guidati da difetti, cioè sviluppare test per il modulo che si intende modificare.

Buona fortuna!

0

Ho anche la possibilità di utilizzare le funzionalità dell'IDE per migliorare la qualità del codice. Per eclissi ciò che vorrei fare:

Nelle preferenze java> stile codice> formattatore - definire il proprio formato e aggiungerlo. dopo di che fai clic con il tasto destro del mouse sul progetto e sulla fonte < ripulisci. Scegli il profilo personalizzato e configura. Ci sono molte cose che puoi fare qui, come la formattazione del codice che ripulisce le importazioni convertendo legacy per loops in quelle migliorate ripulendo il codice inutilizzato e molti altri.

Successivamente avrei fatto le cose suggerite da altre persone come usare checkstyle, pmd, findbugs e così via.

2

Sono stato attraverso questo processo un paio di volte, ho trovato che la soluzione richiede la conoscenza quanto segue:

  • Ci sarà agitazione politica al concetto di fissazione di tali cose?
  • C'è ora uno standard accettato per come queste cose dovrebbero apparire/essere formattate?
  • Ci sono grandi casi di test?

La situazione politica è il più difficile da mitigare, fondamentalmente nessuno piace l'idea di movimento laterale, e passando attraverso il processo di far rispettare formattazione codice e convenzioni di denominazione è molto un movimento laterale. Se riesci a trovare un solido insieme di parametri che giustifichi la tua decisione, il tuo movimento laterale può essere mascherato come un movimento in avanti. Ho trovato che i migliori parametri qui sono sulla falsariga di

"un insieme coerente di standard di codifica si tradurrà in: - 30% meno bug - di sviluppo del 30% più veloce - manutenzione 80% più a basso costo - Il 100% di noi codificatori sarà molto più felice con questo cambiamento "

Non solo tirare fuori questi numeri dall'aria è un trucco. Essere in grado di giustificare questo

Chiaramente non ha senso iniziare questo lavoro a meno che non sia stato acquistato dalle persone che attualmente aggiungono al progetto. Tutti devono essere d'accordo e iniziare a rielaborare questi ideali nel codice attualmente esistente. Ricorda che non tutti usano un IDE (ad esempio codifico tutti i miei java in VIM) e quindi dovresti assicurarti che questo formato sia dettato su un wiki affinché tutti possano vedere (in particolare i nuovi membri del team) e che la pagina wiki abbia download per i vari editor in uso.

Dal momento che è molto probabile che non stiamo parlando solo della formattazione del codice, ma anche del ridenominazione variabile e di un cambio di pattern che influenzano le API pubbliche delle classi, quindi è necessario assicurarsi di avere un set di test molto stabile casi. Se mancano i casi di test, dovresti sempre iniziare dall'esterno nel modello dei test in modo tale che interagiscano come fanno gli utenti. Quindi puoi passare attraverso e refactoring con un grado di fiducia. Una volta che hai un codice che assomiglia ai tuoi sogni, puoi entrare e aggiungere test più vicino a ciascun oggetto. Niente è più doloroso di creare tutti i casi di test, quindi modificare le API e dover modificare tutti i casi di test; ogni volta che ho visto succedere, questo si traduce in un massiccio calo nella copertura del test.