Quali sono i punti chiave di lavorare in modo efficace con il codice legacy? [chiuso]


133

Ho visto alcune volte il libro Lavorare efficacemente con il codice legacy . Quali sono i punti chiave di questo libro?

C'è molto di più da fare con il codice legacy che aggiungere test unitari / di integrazione e quindi refactoring?



2
Ovviamente il punto è aggiungere test e poi refactor. Il libro tratta in gran parte del modo in cui riesci a ottenere un codice incredibilmente contorto in fase di test, e ci sono molti occhi aperti su questo punto. Diciamo solo che Feathers non prende prigionieri!
Kilian Foth,

9
Forse dovresti semplicemente leggere il libro
HLGEM,

Risposte:


157

Il problema chiave con il codice legacy è che non ha test. Quindi è necessario aggiungere alcuni (e poi altro ...).

Questo di per sé richiederebbe molto lavoro, come ha notato @mattnz. Ma il problema speciale del codice legacy è che non è mai stato progettato per essere testabile . Quindi in genere è un enorme casino contorto di codice spaghetti, in cui è molto difficile o assolutamente impossibile isolare piccole parti da testare. Quindi, prima del test unitario, è necessario riformattare il codice per renderlo più testabile.

Tuttavia, al fine di effettuare il refactoring in modo sicuro, è necessario disporre di test unitari per verificare di non aver rotto nulla con le modifiche ... Questa è la cattura 22 del codice legacy.

Il libro ti insegna come uscire da questo problema apportando le modifiche minime e più sicure al codice solo per abilitare i test della prima unità. Questi non hanno lo scopo di rendere il design più gradevole, ma solo di abilitare i test unitari. In effetti, a volte rendono il design più brutto o più complesso. Tuttavia, ti consentono di scrivere test e, una volta che hai messo in atto i test unitari, sei libero di migliorare il design.

Ci sono molti trucchi per rendere testabile il codice - alcuni sono in qualche modo ovvi, altri no. Ci sono metodi che non avrei mai pensato a me stesso, senza leggere il libro. Ma ciò che è ancora più importante è che Feathers spiega cosa rende precisamente testabile un'unità di codice. Devi tagliare le dipendenze e introdurre barriere nel tuo codice, ma per due motivi distinti:

  • rilevamento - al fine di verificare e verificare gli effetti dell'esecuzione di un pezzo di codice, e
  • separazione - al fine di ottenere innanzitutto il pezzo di codice specifico in un cablaggio di prova.

Tagliare le dipendenze in modo sicuro può essere complicato. L'introduzione di interfacce, simulazioni e dipendenza dall'iniezione è pulita e piacevole come obiettivo, ma non è necessariamente sicuro da fare a questo punto. Quindi a volte dobbiamo ricorrere alla sottoclasse della classe sotto test al fine di sovrascrivere un metodo che normalmente ad esempio avvia una richiesta diretta a un DB. Altre volte, potremmo anche aver bisogno di sostituire una classe di dipendenza / jar con una falsa nell'ambiente di test ...

Per me, il concetto più importante introdotto da Feathers è la cucitura . Una cucitura è un punto nel codice in cui puoi cambiare il comportamento del tuo programma senza modificare il codice stesso . La creazione di giunzioni nel codice consente di separare il pezzo di codice in prova, ma consente anche di rilevare il comportamento del codice in prova anche quando è difficile o impossibile eseguire direttamente (ad esempio perché la chiamata apporta modifiche in un altro oggetto o sottosistema , il cui stato non è possibile eseguire una query direttamente dall'interno del metodo di test).

Questa conoscenza ti consente di notare i semi della testabilità nel mucchio di codice più cattivo e di trovare le modifiche minime, meno dirompenti e più sicure per arrivarci. In altre parole, per evitare di rendere "ovvi" i refactoring che rischiano di infrangere il codice senza che te ne accorga, perché non hai ancora i test unitari per rilevarlo.


5
Nota quando la risposta sopra dice "unit test" significa in realtà "test automatici" . Per un'app legacy, gran parte dei test automatici inizialmente utili saranno in realtà test di integrazione (in cui la logica di test esegue una lastra più grande del codice complessivo e può produrre guasti dovuti a difetti in molti luoghi diversi), piuttosto che unità reale test (che mirano ad analizzare solo un modulo ed eseguire porzioni di codice molto più piccole ciascuna).
Lutz Prechelt il

99

Modi rapidi per ottenere i punti chiave di lavorare in modo efficace con il codice legacy


3
Il collegamento MP3 nella pagina di Hanselminutes è interrotto, ma quello su hanselminutes.com/165/… non è - s3.amazonaws.com/hanselminutes/hanselminutes_0165.mp3 .
Peter Mortensen,

Grazie rosston per aver corretto il collegamento PDF. Sembra che objectmentor.com se ne sia andato - forse "Zio Bob" è fallito?
MarkJ,

Non sono sicuro di cosa sia successo al mentore degli oggetti, ma oggigiorno lo zio Bob lavora per 7th Light.
Jules,

40

Lavoro su una base di codice di milioni di righe di codice, alcune risalenti agli anni '80. È solo un software, quindi è solo una questione di scrivere alcuni test unitari, quindi puoi andare e semplicemente riformattarlo e renderlo molto migliore.

La parola chiave qui è solo - è una parola di quattro lettere che non appartiene al vocabolario di nessun programmatore, per non parlare di uno che sta lavorando su sistemi legacy.

Quanto pensi che ci voglia per scrivere un unit test, per testare un'ora di sforzo di sviluppo? Per amor di discussione, diciamo un'altra ora.

Quanto tempo viene investito in quel sistema legacy di 20 milioni di anni fa? Diciamo, 20 sviluppatori per 20 anni volte 2000 ore all'anno (hanno lavorato abbastanza duramente). Ora scegliamo un numero: hai nuovi computer e nuovi strumenti e sei molto più intelligente dei ragazzi che hanno scritto questo pezzo di $% ^^ in primo luogo, diciamo che ne vali 10. Hai 40 anni uomo, beh, hai ...?

Quindi la risposta alla tua domanda è che c'è molto di più. Ad esempio, quella routine ha 1000 righe (ne ho alcune che sono oltre 5000), è eccessivamente complessa ed è un pezzo di spaghetti. Ci vorranno solo (ancora un'altra parola di quattro lettere) un paio di giorni per ricodificarla in poche routine di 100 linee e qualche altro aiuto di 20 righe, giusto? SBAGLIATO. In quelle 1000 righe sono nascoste 100 correzioni di bug, ciascuna richiesta da un utente non documentato o un caso limite oscuro. Sono 1000 righe perché la routine originale da 100 righe non ha funzionato.

Devi lavorare con la mentalità " se non è rotto, non aggiustarlo ". Quando è rotto, devi stare molto attento quando lo aggiusti - mentre lo rendi migliore, non cambi accidentalmente qualcos'altro. Si noti che "rotto" può includere codice non mantenibile, ma che funziona correttamente, che dipende dal sistema e dal suo utilizzo. Chiedi "cosa succede se rovino tutto e lo peggioro", perché un giorno lo farai e dovrai dire al capo dei capi perché hai scelto di farlo.

Questi sistemi possono sempre essere migliorati. Avrai un budget su cui lavorare, una tempistica, qualunque cosa. In caso contrario, vai a crearne uno. Smetti di migliorarlo quando il tempo / denaro è scaduto. Aggiungi una funzione, concediti il ​​tempo di migliorarla un po '. Risolvi un bug: di nuovo, dedica un po 'di tempo extra e miglioralo. Non consegnarlo mai peggio di quanto non fosse quando hai iniziato.


2
grazie per i suggerimenti! Sono tuoi o del libro?
Armand,

3
Probabilmente un po 'di entrambi - ho letto il libro dopo alcuni anni di lavoro e probabilmente dovrei leggerlo agian. Come ogni buon libro, ti farà sfidare un po 'di quello che stai facendo, rinforzare la maggior parte di ciò che fai, ma non ha tutte le risposte per il tuo specifico set di problemi.
mattnz,

7
"Sono 1000 righe perché la routine originale a 100 righe non ha fatto il lavoro." Quindi molto raramente sembra che ciò avvenga davvero. Molto spesso si tratta di 1.000 linee semplicemente perché lo sviluppatore originale si è rimboccato le maniche e ha iniziato a scrivere codice prima di risparmiare anche un momento per pianificare o progettare.
Stephen Touset,

3
No. Sto dicendo che nella maggior parte dei casi (ho incontrato personalmente), 1.000 linee di routine sono chiare indicazioni che le persone hanno iniziato a scrivere codice prima di pensare a come scrivere un'astrazione corretta. Mille routine di linea sono virtualmente troppo complicate per definizione - stai dicendo che una routine di mille righe con centinaia di correzioni di bug nascoste e senza commenti è il segno distintivo di uno sviluppatore responsabile?
Stephen Touset,

16
Se hai creduto in ogni post su questo sito, tutti hanno a che fare con un codice spaghetti da 1000 righe, ma nessuno lo ha mai scritto. Nella mia esperienza, 1000 (e 10000) routine di linea sono il segno distintivo degli sviluppatori che stanno facendo il meglio che possono con ciò che hanno, per fornire ciò che è richiesto loro dal capo che paga i loro stipendi. Trovo offensivo e arrogante il modo in cui così tanti sviluppatori si sentono liberi di commentare a margine senza alcuna conoscenza delle circostanze, senza mai esporre il proprio lavoro alla comunità per criticare.
mattnz,

19

Ci sono due punti chiave da togliere dal libro.

  1. Il codice legacy è qualsiasi codice che non ha copertura di test.
  2. Ogni volta che devi cambiare il codice legacy, devi assicurarti che abbia una copertura.

Come hanno sottolineato altri soccorritori, cercare di aggiornare preventivamente il codice legacy esistente è una commissione da pazzi . Invece, ogni volta che devi apportare una modifica al codice legacy (per una nuova funzionalità o una correzione di bug), prenditi il ​​tempo necessario per rimuovere il suo stato legacy.


6
+1 Punto eccellente: "Ogni volta che devi apportare una modifica al codice legacy, prenditi il ​​tempo necessario per rimuovere il suo stato legacy".
Giovanni,

3
Rimuovendo lo stato Legacy, ottieni il mio voto :)
Rachel

7

In poche parole è vero: aggiungere test e refactoring è tutto.

Ma il libro ti offre molte tecniche diverse per farlo con un codice che è molto difficile da testare e refactoring in sicurezza.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.