Domanda

Attualmente sto lavorando a un pezzo di codice in cui sia l'accesso logico che i dati sono presenti nelle classi GUI. Ovviamente, vorrei migliorare questa situazione.

La struttura attuale è sostanzialmente:

  • Grande palla di fango

L'obiettivo finale è quello di ottenere una struttura simile a DDD:

  • DAL
  • Modello di dominio
  • Livello di servizio
  • Modello di presentazione
  • GUI

Quindi, come affronteresti il ??problema?

  • Big bang
    • Definisci la struttura per lo stato finale e invia il codice alla sua home page definitiva.
  • Dividi e conquista
    • Prova a separare la grande palla di fango in due pezzi. Ripeti fino al termine ...
  • Strangolare
È stato utile?

Soluzione

Non tentare mai " Big Bang " ;. Ti esplode quasi sempre in faccia, dato che è una misura disperata e ad alto rischio quando tutto il resto ha fallito.

Dividi e conquista: funziona bene ... se il tuo mondo ha solo due lati. Nel vero software, devi conquistare così tanti fronti allo stesso tempo, raramente puoi permetterti di vivere in una fantasia in bianco e nero.

Suppongo di aver usato qualcosa come " Strangling " per la maggior parte della mia carriera: trasformare gradualmente il vecchio codice in codice nuovo lucido. Ecco la mia ricetta:

Inizia da qualche parte, non importa dove. Scrivi alcuni unit test per vedere come si comporta davvero il codice. Scopri quanto spesso fa ciò che pensi che faccia e quanto spesso non lo fa. Usa il tuo IDE per riformattare il codice in modo da poterlo testare.

Dopo il primo giorno, prova a indovinare se hai iniziato nel posto giusto per smontare questo mostro. In tal caso, continua. In caso contrario, trova un nuovo posto e ricomincia.

Vantaggi di questa strategia: funziona a piccoli passi, quindi il rischio può essere tenuto sotto controllo e se qualcosa si rompe, se deve essere nel codice su cui hai lavorato la scorsa settimana.

Svantaggio: ci vuole un sacco di tempo e ti sentirai frustrato perché spesso, i progressi sembreranno così lenti fino al "nodo" si apre e improvvisamente, tutto inizia a sistemarsi come per magia.

Altri suggerimenti

Non avevo mai sentito parlare del termine "Applicazione Strangler" - Mi piace. Ove possibile, questo sarebbe sempre un buon approccio, minimizza certamente i rischi ed è abbastanza pragmatico, tagliando via il grande edificio pezzo per pezzo.

Dove ciò non funziona nella mia esperienza è dove sono subito necessari cambiamenti ragionevolmente significativi - cambiamenti che richiedono un po 'di refactoring (o un sacco di hacking). In quella situazione ho spesso scoperto che i cambiamenti che dovevo fare erano proprio nel cuore della grande palla di fango e non c'era altra scelta se non quella di sporcarsi - anche quello che avrebbe dovuto essere la manutenzione standard o piccoli cambiamenti di miglioramento erano semplicemente orribili e un il maggiore refactor era l'opzione migliore.

In quei casi, andrei con dividere e conquistare - il primo obiettivo che cerco sempre è la testabilità, una volta che hai tutto il resto è molto più facile. In realtà, questo è spesso uno dei principali driver che ho per il refactoring lontano dalla grande palla di fango & # 8211; quel tipo di codice è spesso quasi non testabile, si spera che ci siano esempi di input e output dell'interfaccia utente, ma a volte manca anche questo.

Quindi, di fronte al codice in cui tutto è inserito nell'IU, di solito inizio fattorizzando unità discrete di funzionalità in classi e metodi, quindi spingendo quelle parti di codice in un dominio o in un livello di servizio. Farlo a poco a poco riduce notevolmente la possibilità di rompere qualcosa e rende più facile individuare dove si trovava il codice di rottura quando le cose vanno male.

Esegui tutti i casi di test disponibili alla fine di ogni modifica e assicurati di soddisfare ancora una sorta di baseline.

Se scrivi buoni test unitari man mano che procedi, puoi iniziare a ridurre la portata del problema e ho scoperto che presto diventa pratico adottare l'approccio strangolatore - con test unitari decenti o almeno il giusto framework per consentire stesura di test unitari decenti diventa molto più pratico sostituire gradualmente parti di funzionalità.

Mi sono imbattuto in "il metodo Mikado" sembra promettente per attaccare problemi di questa natura.

http://mikadomethod.wordpress.com/

Si parla anche del metodo Mikado di Øredev 2010.

http://oredev.org/2010/ sessioni / Large-scale-refactoring-con-il-mikado-metodo

Big bang / Big riprogettazione / riscrittura del SW ... o qualunque altro nome non funzionerà per un SW vivente. Le ragioni sono:

  • Devi ancora supportare il SW esistente con (probabilmente) le stesse risorse che hai.

  • Probabilmente non hai i requisiti per la riscrittura. Il tuo vecchio codice ha tutti i requisiti integrati al suo interno. Nessuno dei tuoi ingegneri conosce tutti i domini SW e tutti i requisiti.

  • La riscrittura richiederà tempo. Alla fine di questo periodo scoprirai che il SW esistente è cambiato per supportare gli elementi richiesti in questo periodo. il tuo nuovo SW in realtà si è separato dall'originale e sarà necessaria l'unione (che richiederà anche tempo).

Dipende se devi avere sempre uno stato funzionante, in modo da poter correggere e distribuire bug ogni volta che è necessario, allora Devide and Conquer sarebbe una buona soluzione. Se riesci a mantenere il vecchio codice, mentre lavori su uno nuovo (e hai la disciplina per applicare correzioni di bug a entrambe le basi di codice), una riscrittura potrebbe essere una soluzione migliore.

Se per refactoring intendi migliorare il codice senza modificare la funzionalità, inizierei creando una linea di base per i test di regressione automatizzata. Ci sono molti strumenti là fuori per aiutare con questo. Uso TestComlete anche se ci sono buone alternative economiche.

Avendo stabilito una linea di base per i test di regressione, personalmente andrei quindi con dividere e conquistare, poiché nella mia esperienza è più probabile che abbia successo. Una volta che hai una base di test, importa meno quale approccio scegli.

Per me dipende dalla situazione.

Se si tratta di un progetto molto piccolo, sarei tentato di riscriverlo da zero ... tuttavia non hai spesso quel lusso.

In caso contrario, vorrei andare a scheggiarlo pezzo per pezzo. Scriverei unit test per verificare la funzionalità esistente e lentamente utilizzare TDD per trasformare il codice in un sistema elegante e ben progettato. A seconda di quanto tempo impiegherà questo processo, probabilmente inizierà ad apparire come l'applicazione Strangler che hai menzionato sopra.

BigBang è molto rischioso in quanto non esiste un modo semplice per verificare che il sistema aggiornato faccia la stessa cosa di quello precedente.

Divide and Conquer è meno rischioso di BigBang ... ma se è un sistema abbastanza grande può finire per essere problematico quanto BigBang.

La riscrittura totale è un'opzione? Nella mia esperienza, riscrivere da zero spesso può essere più efficiente che cercare di ripulire il disordine esistente. Hai ancora freddo parti del codice esistente ma in un nuovo contesto. E lo stesso vale per la gui e il database se ne hai uno. Riscrivi da zero e porta con te ciò che puoi usare.

Partendo da una nuova architettura pulita e spostando le vecchie parti di codice in questa nuova architettura pezzo per pezzo e rifattorizzarlo per adattarlo al nuovo arco sarebbe una buona opzione. Penso che un approccio dal basso verso l'alto quando si spostano le funzioni sarebbe buono.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top