In una base di codice legacy, come faccio a scoprire rapidamente cosa viene utilizzato e cosa no?

21

Mi è stato chiesto di valutare ciò che sembra essere una base di codice legacy sostanziale, come precursore di un contratto che mantiene quel codebase.

Questa non è la prima volta che mi trovo in questa situazione. Nella presente istanza, il codice è per un sito di gioco multiplayer di alto profilo e abbastanza alto carico, che supporta almeno diverse migliaia di giocatori online contemporaneamente. Come molti di questi siti, questo è un mix di tecnologie front e back-end.

La struttura del sito vista da dentro e fuori, è un casino. Ci sono cartelle con suffisso "_OLD" e "_DELETE" distese dappertutto. Molte cartelle sembrano non servire a niente o hanno nomi molto criptici. Potrebbero esserci molti vecchi script inutilizzati che giacciono anche in cartelle dall'aspetto legittimo. Non solo, ma ci sono indubbiamente molte sezioni di codice defunte anche in script altrimenti operativi (una preoccupazione molto meno urgente).

Questo è un passaggio dai manutentori incumbent, agli sviluppatori / manutentori originali del sito. Come è comprensibilmente tipico in questo tipo di scenari, l'incumbent non vuole avere nulla a che fare con il passaggio di consegne diverso da quello che è richiesto contrattualmente e legalmente per spingerlo al manutentore appena eletto. Quindi estrarre le informazioni sulla struttura del sito esistente dall'incumbent è semplicemente fuori questione.

L'unico approccio che ti viene in mente di entrare nella base di codice è di iniziare dalla radice del sito e lentamente ma sicuramente navigare attraverso gli script collegati ... e ci sono probabilmente centinaia in uso, e altre centinaia che non lo sono. Dato che una parte sostanziale del sito è in Flash, questo è ancora meno semplice poiché, in particolare nelle vecchie applicazioni Flash, i collegamenti ad altri script possono essere incorporati nei file binari (.FLA) piuttosto che nei file di testo (.AS / ActionScript).

Quindi mi chiedo se qualcuno abbia suggerimenti migliori su come affrontare la valutazione della base di codici nel suo complesso per la manutenibilità. Sarebbe meraviglioso se ci fosse un modo per guardare un grafico della frequenza di accesso ai file sul sistema operativo del server web (a cui ho accesso), in quanto ciò potrebbe offrire alcune informazioni su quali file sono più critici, anche se non sarebbe essere in grado di eliminare quei file che non vengono mai utilizzati (poiché alcuni file potrebbero essere utilizzati solo una volta all'anno).

    
posta Arcane Engineer 26.01.2012 - 16:37
fonte

7 risposte

32

Poiché ciò che ti viene chiesto di fare è fornire input per il tuo client per scrivere una proposta appropriata al altro client (proprietario dell'incubo- codice) per qualsiasi lavoro su quel codice, ho intenzione di uscire su un arto e dire che non si sta andando a fare alcun test approfondito o refactoring o nulla su quelle linee a questo punto. Probabilmente hai un tempo molto breve per ottenere una stima approssimativa. La mia risposta si basa sulla mia esperienza nella stessa situazione, quindi, se la mia interpretazione non è corretta, ignorare tutto ciò che segue.

  • Utilizzare uno strumento di spidering per avere un'idea di quali pagine ci sono e cosa è in entrata Anche un semplice strumento linkchecker - non uno specifico "spider per scopi di controllo" - sarà utile a questo proposito.
  • Crea un foglio di lavoro di controllo / inventario di base. Questo potrebbe essere semplice come un elenco di file e il loro tempo dell'ultima modifica, organizzati per directory. Questo ti aiuterà ad avere un senso dell'oscilloscopio e quando arrivi directory come _OLD e _DELETE puoi fare una nota importante che a) la tua valutazione si basa su cose non in quelle directory b) sul presenza di quelle directory e potenziale per cruft / hidden incubi attesta problemi più profondi che dovrebbero essere spiegati per in offerta del tuo cliente , in qualche modo. Non devi spendere un gazillion anni elencando i possibili problemi in _OLD o _DELETE; le informazioni alimenterà l'offerta finale.
  • Dato che stai rivedendo ciò che sembra un'app interamente basata sul web, anche gli strumenti di analisi dei log standard saranno tuoi amici. tu sarà in grado di aggiungere al foglio di calcolo un senso di "questo è nel la top 10 degli script accessibili "o alcuni di questi anche se gli script sono incorporato in file Flash e quindi non è ragguardevole, c'è un massimo probabilità a cui si accede tramite POST o GET e verranno visualizzati in il server registra. Se sai di avere 10 script altamente accessibili, non 100 (o viceversa), questo vi darà una buona idea di come probabilmente andranno lavori di manutenzione.

Anche in un sito complicato, quello che ho delineato sopra è qualcosa che potresti fare in un giorno o un giorno e mezzo. Dato che la risposta che darai al tuo client è qualcosa di simile a "questo sarà un tremendo dolore nel sedere, e qui ci sono alcuni motivi per cui stai solo mettendo il rossetto su un maiale, quindi dovresti fare un'offerta di conseguenza "o" qualsiasi persona ragionevole farebbe un'offerta per non mantenerla ma per ricominciare, quindi dovresti fare un'offerta di conseguenza "o anche" questo non è poi così male, ma sarà un flusso costante di lavoro su qualsiasi dato il lasso di tempo, quindi fai un'offerta di conseguenza ", il punto è che loro stanno facendo l'offerta e quindi non hai bisogno di essere preciso come lo saresti se venissi assunto direttamente per fare un controllo completo dell'architettura e dei contenuti.

    
risposta data 26.01.2012 - 18:17
fonte
4

Raccomando vivamente di refactoring il codice sorgente esistente (al contrario di una riscrittura) usando i pattern trovati nel libro " Funzionante in modo efficace con codice legacy ".

Il libro descrive diversi meccanismi per la copertura efficiente del codice legacy nei test unitari, in modo tale da poter iniziare a rifattare il codice in modo sicuro. Il libro è suddiviso in parti, una che descrive la filosofia dietro l'approccio, e poi diversi capitoli che risolvono problemi particolari, come "Ci vuole sempre un cambiamento", "Non ho molto tempo e ho bisogno di cambiarlo" e "Non riesco a portare questa classe in un'imbracatura di prova". Ciascuno di questi capitoli dispone di tecniche dettagliate e comprovate che consentono di apprendere come applicare le migliori pratiche nel test dei problemi del mondo reale.

La lettura del libro mi ha lasciato un vero senso del fatto che "non siamo soli" ... molti di noi, o forse tutti noi, stanno lavorando con basi di codice complesse che sono diventate difficili da gestire. Le tecniche elencate nel libro mi hanno dato molte speranze e personalmente sono stato in grado di applicarle quasi immediatamente.

Il post sul blog di Joel Spolsky fa un ottimo lavoro per spiegare perché è meglio mantenere una base di codice funzionante esistente anziché iniziare da zero. Ho scelto una citazione dall'articolo che la riassume, ma è una lettura fantastica.

"There's a subtle reason that programmers always want to throw away the code and start over. The reason is that they think the old code is a mess. And here is the interesting observation: they are probably wrong. The reason that they think the old code is a mess is because of a cardinal, fundamental law of programming:

It’s harder to read code than to write it.". - http://www.joelonsoftware.com/articles/fog0000000069.html

    
risposta data 26.01.2012 - 17:59
fonte
2

In una tipica base di codice Java, prenderò in considerazione l'utilizzo di strumenti come PMD, FindBugs o Sonar e quindi proverò a capire gli strumenti che riportano (codice morto, codice non documentato, codice duplicato, ecc.)

Sulla base dei rapporti cercherò di trovare i diversi livelli dell'applicazione / sito (livello aziendale, DB, SQL, ecc.)

Se i layer sono accoppiati (html all'interno di servlet, sql all'interno di codice java) Inizierò prima disaccoppiando ognuno di questi passaggi che dovrebbero essere considerati come isolati e potreste impegnarvi alla fine di ognuno (iniziando un ramo quindi make merge).

    
risposta data 26.01.2012 - 17:41
fonte
1

Dalla tua descrizione sembra che questo codice abbia raggiunto lo stato non mantenibile, il che significa che l'approccio migliore è probabilmente una completa riscrittura. Gli sviluppatori avrebbero stipendi molto più piccoli se ci fossero strumenti di qualità che hanno funzionato per mantenere una base di codice disordinata mantenibile. È possibile passare e ripulire il vecchio codice non necessario dalle cartelle, ma è un'attività manuale e probabilmente non si otterrà comunque nulla senza eccessive quantità di tempo. Sto solo indovinando qui, ma scommetto che il codice di lavoro stesso è tanto confuso quanto la struttura dei file, il che significa che anche quando si riesce a far sì che il code-based sia rifilato al codice attivamente funzionante, sarà comunque un incubo per aggiornare o correggere qualsiasi cosa.

Vorrei sottolineare che lo sforzo richiesto per ottenere il codice esistente in uno stato mantenibile sarebbe uguale o maggiore dello sforzo di ricominciare da una riscrittura. parte del mantenimento di qualcosa è sapere quando "prenderlo dietro il capannone e sparargli".

    
risposta data 26.01.2012 - 17:22
fonte
1

Un web crawler potrebbe aiutarti a determinare quali URL sono accessibili. Soprattutto se è abbastanza intelligente da estrarre link da Flash o JavaScript. Una volta che hai un elenco di pagine web, passa attraverso di loro ed elenca i file a cui si riferiscono. Tutto ciò che è rimasto dopo questo processo dovrebbe essere considerato come codice morto.

    
risposta data 26.01.2012 - 18:38
fonte
0

Nota: ho messo un accento sull'utilizzo del database, mentre chiedevi l'utilizzo del codice stesso. La risposta vale comunque per entrambi i casi in tutti i punti che ho citato.

Hai già risposto in parte alla tua domanda nell'ultimo paragrafo: vedi a cosa accede mentre l'applicazione è in esecuzione.

  1. Puoi profilare il database e chiedere al profiler di registrare tutte le query per un giorno. Vi darà una panoramica degli oggetti di database più utilizzati, ma non dirà quali non vengono mai utilizzati. Inoltre, devi sempre stare attento con i risultati: per esempio una tabella può essere utilizzata esclusivamente attraverso stored procedure, ma quando guarderai le query dal profiler, sembrerebbe che la tabella non sia affatto utilizzata. / p>

  2. La revisione del codice sorgente, la ricerca di query è più utile e, dopo aver raccolto tutte le query, puoi avere una buona comprensione dell'utilizzo del database, non in termini di frequenza (questo è dove un profiler è a portata di mano), ma in termini di tabelle usate / non utilizzate. Purtroppo, per un codice mal scritto / non mantenuto per anni codebase, può essere estremamente difficile e soggetto a errori , soprattutto se le query sono costruite dinamicamente (immagina un metodo che, in una select , utilizza un parametro come il nome della tabella, come puoi sapere quali sono i possibili valori del parametro semplicemente guardando il codice sorgente?).

  3. Analisi statica e alcuni compilatori potrebbero anche rivelare codice guasto, ma non ti danno ancora la risposta che desideri.

  4. Analisi dei dati stessi o dei metadati del database possono rivelare alcune informazioni interessanti. Ad esempio, sarebbe facile affermare che la tabella LogonAudit(uniqueidentifier LogonAuditId, datetime LogonEvent, ...) non è più utilizzata se contiene 10.000 record al giorno per gli anni dal 2006 al 2009 e nessun record da settembre 18 th , 2009. Lo stesso non è vero per una tabella che contiene i rientri dei dati per essere principalmente di sola lettura.

Questi quattro punti insieme ti forniranno l'elenco delle tabelle utilizzate. Quelli rimanenti sono usati o meno. Puoi fare asserzioni e testarle, ma senza una buona copertura dei test unitari, non sarebbe facile. Anche un modo "facile" fallirebbe. Ad esempio, se hai una tabella products_delme_not_used , puoi affermare che la tabella non viene utilizzata affatto e controlla "products_delme_not_used" nel codice. Questo è ottimistico: non è insolito trovare il candidato DailyWTF come questo in una vecchia base di codice:

// Warning: WTF code below. Read with caution, never reuse it, and don't trust
// the comments.

private IEnumerable<Product> GetProducts()
{
    // Get all the products.
    return this.GetEntities<Product>("PRODUCT");
}

private IEnumerable<T> GetEntities<T>(string tableName)
{
    // Everyone knows that SQL is case sensitive.
    tableName = tableName.ToLower();

    if (tableName == "user" || tableName == "product")
    {
        // Those tables were renamed recently in the database. Don't have time
        // to refactor the code to change the names everywhere.
        // TODO: refactor the code and remove this 'if' block.
        tableName += "s";
    }

    if (this.IsDelme(tableName))
    {
        // We have some tables which are marked for deletion but are still
        // used, so we adjust their name.
        tableName = this.Delme(tableName);
    }

    return this.DoSelectQuery<T>("select top 200 * from " + tableName);
}

private bool IsDelme(string name)
{
    // Find if the table is among candidates for removal.
    List<string> names = this.Query<string>("select Names from DelmeTables");
    return names.Contains(name);
}

private string Delme(string name)
{
    // Return the new name for a table renamed for deletion.
    return string.Join("_", new [] { name, "delme", "not", "used" });
}

Riesci a capire che questo codice utilizza effettivamente la tabella products_delme_not_used ?

Se fossi in te, vorrei:

  1. Mantieni tutti gli oggetti del database in posizione,
  2. Riforma l'intera applicazione (se ne vale la pena),
  3. Documento (durante il refactoring) dell'applicazione e in particolare l'utilizzo del database.

Una volta completati gli ultimi due passaggi, probabilmente avrai una migliore comprensione dell'utilizzo del database, che ti aiuterà a capire i nomi delle tabelle che non sono più utilizzate e potrebbe rimuoverli più o meno in sicurezza.

    
risposta data 26.01.2012 - 17:24
fonte
0

Mi sembra che tu abbia bisogno di informazioni sufficienti per creare una citazione, quindi mi concentrerò su quello sforzo.

Vorrei provare a determinare quanti casi d'uso ci sono coinvolti in questo sito. Questo in genere ti dà un'idea di quanto sia grande e complicato il sito e quanto tempo ci vorrà per ricreare o mantenere il sito / l'applicazione.

Sì, è vero che a volte il codice non viene più utilizzato e renderà l'applicazione un po 'più grande di quanto sia in realtà, ma non credo che questo influenzerà i numeri di oltre il 20% al massimo, quindi non mi preoccuperei di quella parte.

Guardando il codice sorgente, le pagine web e le tabelle del database dovrebbero aiutarti a scoprirlo.

Potresti anche prendere in considerazione la possibilità di limitare il numero di ore al mese che spenderesti per questo progetto per la tariffa predeterminata per proteggerti.

Per quanto riguarda la scoperta di ciò che viene utilizzato e non utilizzato, non c'è davvero un modo semplice. Gli strumenti di analisi del codice possono essere d'aiuto, ma dal momento che hai a che fare con un male così vario non credo esista alcun singolo strumento che possa aiutarti. Per ogni area specifica puoi probabilmente trovare uno strumento di analisi del codice che possa aiutarti.

    
risposta data 26.01.2012 - 18:23
fonte

Leggi altre domande sui tag