Quando il codice è "legacy"? [chiuso]


63

L'abbiamo fatto tutti, abbiamo etichettato alcuni codici (spesso roba che abbiamo ereditato) come "legacy"? Ma è ancora utilizzato nei sistemi di produzione - quindi è davvero legato? E cosa lo rende legato? Dovremmo evitare questa etichettatura ingiustificata di codice perfettamente funzionante; dove l'etichettatura è una pura convenienza che ci consente di passare attraverso nuove cose e mantenere l'alta direzione piacevole e felice?


Riepilogo delle risposte

Guardando attraverso le risposte vedo quattro temi generali. Ecco come vedo la ripartizione:

  1. Qualsiasi codice che è stato consegnato: 6
  2. Sistemi morti: 2.5
  3. Nessun test unitario: 2
  4. Gli sviluppatori non sono in giro: 1.5


1
È un codice legacy non appena viene consegnato e funziona.
Martin Beckett,

23
è un codice legacy se non lo hai scritto ;-)
Steven A. Lowe,

20
È un codice legacy se tutti quelli che lo hanno scritto sono in pensione o morti, e se quelli che continuano a mantenerlo lo desiderano. Altrimenti, si chiama semplicemente la base di codice esistente.
unpythonic il

3
@ StevenA.Lowe, dato abbastanza tempo, si tratta di codice legacy, anche se ho fatto scrivere.
Kyralessa,

Risposte:


43

Sono piuttosto parziale al sommario di Wikipedia stesso:

Un sistema legacy è un vecchio metodo, tecnologia, sistema informatico o programma applicativo che continua ad essere utilizzato, in genere perché funziona ancora per le esigenze degli utenti, anche se sono ora disponibili tecnologie più recenti o metodi più efficienti per eseguire un'attività.

Molto di ciò che altre persone descrivono nelle loro risposte sono le ragioni per cui il codice diventa "eredità". Ma la domanda essenziale in sé è questa:

Ma è ancora utilizzato nei sistemi di produzione - quindi è davvero legato? E cosa lo rende legato?

Il fatto che sia ancora utilizzato nella produzione è proprio ciò che lo rende ereditato . Se il codice non funziona correttamente o non viene più utilizzato in produzione, il codice viene rispettivamente "rotto" o "ritirato". Legacy significa che è ancora in uso e funziona bene, ma incorpora design o tecniche che non sono più di uso comune.

Qualsiasi codice o sistema che si desidera (a) aggiornare / aggiornare, ma non è possibile, o (b) è ancora nel mezzo dell'aggiornamento, è un sistema legacy. Ciò non significa refactoring o pulizia del codice generale, ma modifiche significative al design, possibilmente utilizzando un nuovo framework o persino una nuova piattaforma.

Esistono diversi motivi per cui i sistemi o il codice potrebbero diventare legacy:

  • Mancanza di manutenzione regolare o marciume del software . Chiaramente se l'applicazione non viene mantenuta regolarmente, non sarà al passo con i grandi cambiamenti nel mondo del software. Ciò potrebbe essere dovuto alla semplice negligenza o potrebbe essere una scelta deliberata basata su priorità aziendali o vincoli di bilancio.

  • Mancanza di test. Un'altra risposta fa riferimento all'affermazione iperbolica di un autore popolare di qualsiasi codice non coperto da test essendo codice legacy. Questa in realtà non è una definizione accurata ma è una possibile causa principale; senza buoni test (automatizzati o manuali), gli sviluppatori diventano timidi e hanno paura di fare grandi cambiamenti perché si preoccupano di rompere qualcosa, portando così il "marciume del software" sopra.

  • Rev-bloccando, un fattore spesso trascurato che è particolarmente insidioso nei progetti che utilizzano grandi librerie o framework open source (anche se l'ho visto accadere anche con strumenti commerciali). Spesso ci sarà una grande personalizzazione nel framework / libreria, rendendo un upgrade proibizionalmente difficile o costoso. Pertanto, il sistema diventa legacy perché funziona su una piattaforma precedente (e forse non più supportata).

  • Il codice sorgente non è più disponibile, il che significa che il sistema può essere aggiunto solo e mai, mai modificato. Dal momento che questi sistemi devono essere riscritti al fine di aggiornare, anziché rivedere in modo incrementale / iterativo, molte aziende non si preoccuperanno.

Tutto ciò che rallenta o interrompe gli aggiornamenti di una base di codice può portare a tale base di codice diventare legacy.

Ora la domanda separata, non dichiarata ma implicita è: cosa c'è di sbagliato nel codice legacy? Viene spesso usato come termine peggiorativo, quindi la domanda:

Dovremmo evitare questa etichettatura ingiustificata di codice perfettamente funzionante?

E la risposta è no, non dovremmo; l'etichettatura è giustificata e il termine stesso implica chiaramente un codice funzionante. Il punto non è che è una funzione, ma come funziona.

In alcuni casi non c'è niente di sbagliato nel codice legacy. Non è una parolaccia. I codici / sistemi legacy non sono male. Hanno appena raccolto un po 'di polvere - a volte un po', a volte molto.

L'eredità diventa obsoleta quando il sistema non può più soddisfare (tutte) le esigenze del cliente. Quella etichetta è quella che dobbiamo stare attenti. Altrimenti, è semplicemente un'equazione costo / beneficio; se il costo dell'aggiornamento sarebbe inferiore al costo dei suoi benefici (inclusi i costi di manutenzione futuri inferiori), allora l'aggiornamento, altrimenti, lascia perdere. Non c'è bisogno di sputare la parola "legacy" con lo stesso tono che normalmente si riserva per "audit fiscale". È una situazione perfettamente OK in cui trovarsi.


Detto questo, anche il controllo fiscale dovrebbe essere una situazione perfettamente OK.
Florian Margaine,

Direi: sistema che non può più essere scalabile con lo stack tecnologico esistente.
Ramiz Uddin,

40

Di solito significa che è scritto in una lingua o basato su un sistema in cui in genere non si esegue un nuovo sviluppo.

Ad esempio, la maggior parte dei luoghi non scrive nuovi programmi in Cobol. Tuttavia, gran parte della loro attività può essere eseguita su app scritte in Cobol. Quindi, quelle app sono etichettate "Legacy".


Sono più d'accordo con questa risposta. L'eredità si basa più sull'essere bloccati su una piattaforma obsoleta che sull'essere un codice fastidioso (ma moderno) che non si desidera supportare. Il codice legacy è spesso abbastanza buono (altrimenti a nessuno importerebbe se lo lasciassi alle spalle!) Ma di solito è legato a hardware obsoleto e linguaggi / librerie / database / ecc. Obsoleti.
Satanicpuppy,

3
@Satanicpuppy: Semplicemente non posso essere d'accordo - ho affrontato (per esempio) un po 'di Java che sicuramente non era legato a particolari hardware, librerie o database - ma era "ereditato" come (e lo era) riscritto in Java, quindi la lingua non era il problema). Ho anche affrontato con un po 'di codice che è stato legato ad hardware specifico, ma era ancora solo a malapena scivolando nella categoria "legacy".
Jerry Coffin,

4
@jerry: Allora, cosa l'ha reso legacy? L'eredità non è sinonimo di "cattivo".
Satanicpuppy,

1
Nel caso a cui sto pensando, era un sistema distribuito abbastanza grande (costruito attorno a BEA Tuxedo). Il design sembrava basato su scenari di libri di testo che hanno lo scopo di insegnare la sincronizzazione massimizzando il numero di volte / luoghi necessari per la sincronizzazione. Questo (in un certo senso) ha senso per un libro di testo, ma è orribile per i disegni reali. Era abbastanza grande che persino progettare un sostituto fosse un progetto pluriennale. La sostituzione doveva essere effettuata in fasi senza tempi di inattività, poiché il sistema era assolutamente necessario per l'azienda.
Jerry Coffin,

1
@Cawas: Mi sembra che la risposta di @ Chad si applicherebbe quando / se il nuovo sistema fosse fatto in una lingua diversa, o usando hardware diverso, ecc. Questo veniva ri-sviluppato ancora usando Java, usando ancora Tuxedo, ecc. Non lo vedo come applicabile.
Jerry Coffin,

28

Legacy significa qualsiasi codice che preferiresti sostituire piuttosto che lavorare. Dato l'atteggiamento della maggior parte dei programmatori verso la maggior parte del codice esistente, che di solito include quasi tutto tranne ciò che stai scrivendo attivamente al momento (e su un grande progetto in cui devi programmare un design congelato, anche ciò che stai scrivendo al il momento può anche essere incluso).

  1. L'enfasi "piuttosto" ha lo scopo di comunicare che il codice legacy significa anche che sei bloccato a lavorarci anche se preferisci non farlo. Non sono sicuro che l'enfasi fosse sufficiente però. I motivi possono variare. Alcuni sono davvero troppo grandi e complessi da sostituire. Altri sono interfacce per altri sistemi. Altri ancora sono guidati dalla politica e dalle personalità (ad esempio, il codice è orribile, ma la ragazza dello stand è stata fantastica).
  2. Un altro punto che potrei non aver sufficientemente sottolineato è che mentre la qualità del codice può essere un fattore, raramente (se mai) è l'unico fattore - e spesso nemmeno uno particolarmente importante.
  3. Penso che le persone che spingono i test unitari come unico fattore determinante siano come il ragazzo che guarda sotto il lampione l'orecchino che sua moglie ha lasciato cadere a un isolato di distanza. La luce potrebbe essere migliore, ma stai ancora guardando nel posto sbagliato. Pensa prima di bere il Kool-Aid .
  4. (Un corollario a 3.) Mi sembra che alcune persone stiano parlando più di come desiderano che le cose siano piuttosto che di come sono realmente. Se John Conways ' Gioco della Vita per di Apple IIc Inoltre non è retaggio, è perché è sufficientemente piccolo e semplice che è facile da re-implementare da zero. Il test di unità più perfetto mai scritto non cambierà quel singolo iota .

L'ultimo punto porta ad altri due punti che penso siano spesso veri.

Innanzitutto, il codice viene spesso mantenuto come eredità, anche quando in realtà non dovrebbe esserlo. I gestori di livello superiore in genere presumono che la reimplementazione di un sistema costerà tanto o più dell'implementazione iniziale, cosa che raramente è vera.

In secondo luogo, i test unitari sono un'arma a doppio taglio. Rendono fin troppo facile pensare che i cambiamenti localizzati nell'implementazione siano ciò che conta davvero. Per apportare miglioramenti significativi in ​​un sistema più grande, spesso (di solito?) È necessario modificare abbastanza la progettazione complessiva in modo che molti (se non la maggior parte) dei test unitari diventino irrilevanti. Sfortunatamente, la presenza di test unitari e l'atteggiamento che essi generano possono rendere fin troppo facile ignorare i cambiamenti che sono davvero necessari.

Forse un esempio di ciò sarebbe di aiuto: supponiamo che un programma abbia una libreria UI con grandi test unitari e diversi programmi che usano quella libreria. Qualcuno nella direzione superiore si convince che "abilitare il web" è importante (e, solo per ragioni di argomento, supponiamo che in questo caso abbia effettivamente ragione su questo). Dopo un'attenta revisione, i dirigenti intermedi ritengono che il loro attuale test unitario sia sufficiente per poter passare da un'interfaccia utente visualizzata tramite la funzionalità di windowing del sistema operativo locale a essere visualizzata in remoto tramite HTML / CSS / AJAX, mantenendo al contempo tutta la convalida dell'input originale.

Fantastico, vero? Mostra quanto utile può essere il test unitario. Abbiamo sostituito l'intera implementazione dell'intera interfaccia utente, ma ci siamo assicurati che l'aspetto, la funzionalità e la funzionalità rimanessero praticamente coerenti e che tutti gli input dell'utente fossero convalidati per garantire l'integrità dei dati. I test unitari hanno salvato la giornata!

O no! Quella grande, altamente flessibile, attentamente testata libreria dell'interfaccia utente ha aiutato tutte le persone coinvolte al fatto che per questo programma nel suo mercato con i suoi utenti, un'interfaccia utente basata sul web è assolutamente la cosa sbagliata su cui lavorare. Ciò che è veramente necessario è un servizio Web con un'interfaccia RESTful e nessuna UI assoluta .

Ora, è certamente vero che i test unitari non rimuovono di per sé la capacità delle persone di comprendere il loro mercato o rendersi conto che è davvero necessario. Allo stesso tempo, la vecchia linea su martelli e chiodi viene quasi alla mente. Può essere anche peggio quando non solo avere un martello, ma hanno un sacco di esperienza con questo martello, e so che è un davvero un martello di alta qualità che funziona incredibilmente bene in molte situazioni diverse. Il fatto stesso che sia così bravo in così tante cose in così tante situazioni rende ancora più difficile riconoscere quando è completamente lo strumento sbagliato per il lavoro da svolgere.


3
Vedi, ora non so se contrassegnarlo o no, purtroppo è vero, ma mi chiedo se è un atteggiamento di cui abbiamo bisogno per allontanarci ...
Nim

+1. Stavo per rispondere a qualcosa nella stessa misura. Legacy è qualsiasi codice utilizzato anziché gestito attivamente.
Denis de Bernardy,

@Nim: non credo sia un atteggiamento da cui "noi" dobbiamo allontanarci. È una semplice affermazione dell'ovvio. :-) Pensaci un attimo e chiediti cosa considereresti un codice legacy se dovessi arrivare in un nuovo ambiente; sarà tutto tranne le cose nuove e interessanti che vengono sviluppate attivamente.
Denis de Bernardy,

@Jerry, quindi non ti piacciono i test unitari allora? ;)
Nim

1
@Nim: Non è così - penso che siano utili, ma molto meno della panacea come sono spesso rappresentati.
Jerry Coffin,

17

Il codice legacy di solito è orfano in qualche modo. Lo sviluppatore principale, l'unico che lo ha capito, è stato investito da un autobus e le sue note sono state scritte nel suo dialetto ucraino nativo, che ora è una lingua morta. O, in alternativa, qualsiasi cosa scritta in Visual Basic 6.0 .

Lavoro sempre su codice legacy. Direi che le caratteristiche sono:

  • Non può essere esteso senza grandi sforzi
  • Non può essere facilmente migrato su nuovo hardware
  • È troppo critico per essere facilmente sostituito

Se non ha queste caratteristiche, probabilmente non è eredità. Se non ti piacciono gli script Perl dei tuoi predecessori , simpatizzo, ma non credo che sia eredità. Di recente ho ammodernato alcuni script Perl di 15 anni che erano collegati a un database Sybase obsoleto . Quella era una torta rispetto a fare anche il più piccolo cambiamento al nostro terribile sistema contabile COBOL .


Spaventoso, anche il nostro sviluppatore principale è ucraino ... ahah ... Sono d'accordo con la parte centrale della tua risposta, il primo punto - non tanto - penso che dipenda da come è impostato il tuo team di sviluppo.
Nim,

1
lol, probabilmente sei riuscito a offendere (autisti di autobus, la lingua ucraina e gli sviluppatori VB6) tutto in un paragrafo. Ma dannazione ho riso :)
Darknight,

Sono un viaggiatore nel tempo dal 1999, vuoi dire che Visual Basic 6 è ereditato dal 2011?
hjk,

@hjk Direi praticamente qualsiasi cosa dopo l'avvento di C # / asp.net nel 2005 sarebbe su un terreno traballante, ma certamente una volta che la fine del supporto da parte di Microsoft è
arrivata

12

Nel suo libro, Lavorare efficacemente con il codice legacy , Michael Feathers definisce il codice legacy come codice che non è coperto da test unitari. Questa è una definizione, con cui sono d'accordo. Vedo anche il codice legacy come vecchio, ma ancora utilizzabile.


24
Questo mi sembra il caso di tentare di definire "tutto ciò che non segue la mia metodologia prescelta". Non è niente più o meno di una tattica di dibattito a buon mercato, fondamentalmente semplicemente prendere la legge di Godwin e ammorbidire la lingua (a malapena) abbastanza da impedire ai lettori di riconoscere immediatamente che non è altro che un attacco non supportato (e spesso insopportabile) a chiunque non segua le sue preferenze.
Jerry Coffin,

4
@Jerry: sono d'accordo con la definizione di Feather. Il codice senza Unit-Tests è un orrore con cui lavorare. Se decidi di voler riformattare alcune parti di esso in modo che sia più facile ragionarlo, dimenticalo! potresti introdurre bug e il codice probabilmente non è testabile così com'è! Trovo la definizione di Feather non convenzionale, eppure è qualcuno che si è guadagnato da vivere lavorando con il codice legacy.
divorò l'elisio il

10
@devoured: i test unitari non sono una cartina di tornasole accurata per la capacità di lavorare con il codice. Ho affrontato il codice che mancava dei test unitari, ma era un gioco da ragazzi - e con il codice che aveva test unitari, ed era ancora un incubo. In definitiva, i test unitari non risolvono nulla di per sé. I test unitari per un progetto in cui (ad esempio) la divisione in unità è stata eseguita in modo inadeguato possono ancora essere assolutamente inutili e l'intero progetto (compresi i test) deve essere eliminato e sostituito per produrre qualcosa di utile.
Jerry Coffin,

6
Sono d'accordo con i commenti di Jerry. L'assenza di unit test è solo uno dei tanti odori di codice che potrebbero (o non potrebbero ) indicare cattiveria.
smci,

4
Sono di nuovo d'accordo con la definizione di Feather e divorato. L'assenza del test unitario è tutto poiché questo significa che anche il frammento di codice più bello manca le sue specifiche. I test unitari rappresentano il 51% della documentazione e il 100% delle specifiche del codice. Un codice che manca di gran parte della sua documentazione e tutte le sue specifiche dovrebbero essere giustamente classificati come legacy.

8

Tecnicamente, l'eredità è qualsiasi codice pronto per essere scritto. Quindi, non appena è in produzione, è eredità. Perché c'è già valore lì, non puoi semplicemente buttarlo fuori ... Devi affrontarlo.

È "prima del tuo tempo" ma "ancora mal di testa" .


5

Il codice legacy è un codice che rimane solo nella base di codice perché molte cose smetterebbero di funzionare diversamente. In altre parole: l'unica ragione per essere è la compatibilità con le versioni precedenti.

Preferiresti cambiarlo o addirittura buttarlo via, ma non puoi perché spezzerai tutto il codice basandoti su di esso (che potrebbe essere un codice che non puoi adattare di conseguenza). Pertanto devi mantenerlo (e talvolta anche mantenerlo), ma desideri che tutto il nuovo codice non sia scritto contro di esso.

Un esempio sono i metodi obsoleti dell'API di una libreria. Sono ancora lì, quindi se chiunque aggiorna la libreria può ancora costruire il suo progetto, ma sono contrassegnati come deprecati e il compilatore dovrebbe avvisarti.

Un altro esempio sono tutti quegli strani trucchi che Microsoft fa per far funzionare i programmi scritti per le versioni del loro sistema operativo che hanno completamente deprecato. Il culmine di questo essere:

Ne ho sentito parlare per la prima volta da uno degli sviluppatori del gioco di successo SimCity, che mi ha detto che c'era un bug critico nella sua applicazione: usava la memoria subito dopo averla liberata, un no-no importante che funzionava bene su DOS ma non funzionerebbe sotto Windows in cui è probabile che la memoria liberata venga immediatamente recuperata da un'altra applicazione in esecuzione. I tester del team di Windows stavano attraversando varie applicazioni popolari, testandole per assicurarsi che funzionassero bene, ma SimCity ha continuato a bloccarsi. Lo hanno riferito agli sviluppatori Windows, che hanno smontato SimCity, lo hanno esaminato in un debugger, hanno trovato il bug e hanno aggiunto un codice speciale che controllava se SimCity era in esecuzione e, in tal caso, ha eseguito l'allocatore di memoria in una modalità speciale in cui potrebbe ancora usare la memoria dopo averla liberata.
- Joel on Software


4

L'eredità implica l'eredità. Il codice legacy è semplicemente il codice che erediti dal passato. È un codice legacy anche se l'hai scritto tu stesso prima!

Tutte le altre considerazioni derivano fondamentalmente dal fatto che non l'hai scritto specificamente per il tuo progetto attuale. Non è necessariamente una cosa negativa di per sé.


Il passato potrebbe essere 1 giorno, 1 ora o 1 anno. Questo non lo rende legacy.
Vince Panuccio,

2

La mia opinione è che ciò che è considerato codice legacy dipende da più cose e il tag 'legacy' è probabilmente specifico dell'organizzazione.

Se l'hardware / sistema operativo su cui è in esecuzione sono obsoleti e sono stati interrotti dal fornitore, avvertire 1.

Se è più lavoro cercare di ripararlo, piuttosto che riscriverlo, per qualsiasi motivo

  • gli sviluppatori originali sono spariti
  • il programma è scritto male
  • può essere fatto meglio su una piattaforma più recente e vale comunque la pena per l'azienda

fare così

  • la fonte originale non è più disponibile e / o pezzi mancanti

Colpo 2.

Una fusione di più organizzazioni in una sola - Strike 3 - probabilmente una parte verrà etichettata come eredità.

Esiste un'alternativa migliore e più economica venduta come applicazione e / o servizio di terze parti - strike 4.

L'organizzazione è qualcosa di simile a un ospedale o un distretto scolastico in cui la coerenza è valutata rispetto alle nuove tecnologie quando si tratta di operazioni quotidiane? Ci vorrà più tempo perché un'applicazione venga considerata legacy rispetto alla stessa applicazione in un'organizzazione commerciale / competitiva.

Se la società è una piccola società di sviluppo che continua a migliorare / supportare l'applicazione per fare ciò di cui i clienti hanno bisogno, viene considerata un codice legacy o solo un codice "vecchio". Conosco una società di nome Mc2Ok: hanno sviluppato il software su quello che sembra essere stato Windows 3.1 e hanno continuato a portarlo avanti. Ha ancora l'aspetto di Windows 3.1, ma ha anche aggiunto un'interfaccia web. È una società di sviluppo per due persone (la mia ipotesi), e direi che quando smetteranno di lavorarci, sarà considerata un'eredità e il tempo di migrare un anno o due dopo se la usi. Ma potrebbero essere altri 10 o più anni.

A volte quando la gestione cambia, può cambiare in ondate che hanno molti effetti a cascata ... A seconda del peso della nuova gestione, può rendere molte applicazioni legacy che altrimenti potrebbero andare bene.

Ogni organizzazione, credo, deve definire cosa significhi per loro "codice legacy". Ho usato per guardare attraverso il Times Domenica annunci ogni settimana per vedere ciò che le organizzazioni stavano cercando. Quello era il mio barometro per ciò che non era più rilevante (vale a dire, eredità). Bene, il Sunday Times non è più rilevante :-) E possiamo generalizzare che COBOL è legacy, ASP Classic è legacy, ecc ... Ma credo che ogni organizzazione debba decidere quando un'applicazione deve essere considerata legacy.


+1, bella risposta - meglio considerare qualcosa di legato dal punto di vista dell'org ...
Nim

0

Il codice è eredità quando si ha paura di cambiarlo, perché potrebbe romperlo. È ancora più doloroso quando l'intero sistema può essere compromesso dalle modifiche a quel codice.

Questo è il motivo per cui concordo anche con la definizione di Michael Feathers. Il codice che ha buoni test unitari può essere modificato senza paura.

Penso anche che il codice legacy non abbia nulla a che fare con quanti anni ha. Si può scrivere il codice legacy dall'inizio.

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.