Come ti immergi in basi di codice di grandi dimensioni?


145

Quali strumenti e tecniche usi per esplorare e apprendere una base di codice sconosciuta?

Sto pensando a strumenti come grep, ctagsunit test, test funzionali, generatori di diagrammi di classe, grafici di chiamate, metriche di codice come sloccounte così via. Sarei interessato alle tue esperienze, agli helper che hai usato o scritto e alle dimensioni della base di codice con cui hai lavorato.

Mi rendo conto che conoscere una base di codice è un processo che si verifica nel tempo e la familiarità può significare qualsiasi cosa, da "Sono in grado di riassumere il codice" a "Posso refactoring e ridurlo al 30% delle dimensioni". Ma come iniziare?


3
Vorrei vedere anche come viene data una risposta; di solito finisco per riscrivere tutto se il codice è troppo complesso (o scritto male), e questo è probabilmente inaccettabile / poco saggio per i grandi progetti.
Jeffrey Sweeney,

Risposte:


55

quello che ho sempre fatto è il seguente:

Apri più copie del mio editor (Visual Studio / Eclipse / What) e quindi esegui il debug e fai delle interruzioni di riga attraverso il codice. Scopri il flusso del codice, impila la traccia per vedere dove sono i punti chiave e vai da lì.

Posso guardare il metodo dopo il metodo, ma è bello se posso fare clic su qualcosa e quindi vedere dove viene eseguito il codice e seguire. Fammi un'idea di come lo sviluppatore voleva che le cose funzionassero.


3
Sì, imposta un punto di interruzione su un pulsante che ha lanciato un importante pezzo di logica e fai un passo avanti. Questo è quello che faccio sempre.
Joeri Sebrechts,

1
+1 Sì, è quello che faccio anche io, ma non conosco alcun modo per semplificare il lavoro. Nella mia esperienza, possono essere necessarie settimane prima che mi senta sicuro di apportare modifiche e mesi prima che io sia "a casa" nel codice. Sicuramente aiuta se puoi porre domande agli sviluppatori.
Mike Dunlavey,

1
inoltre: di solito inizio con una funzione. Diciamo che voglio sapere come si inviano e-mail? quindi cerco "sendEmail", punto di interruzione lì, e poi faccio come descritto. Poi scopri qualche componente magico che fa qualcosa, e vai in quello, e vedi come
FUNZIONA

1
+1, ma a volte prima di impostare i punti di interruzione, aggiungo la funzione di stampa nella prima riga di quasi tutte le funzioni per vedere le funzioni che chiamano gerarchia.
sig.

@mrz È un'idea interessante aggiungere la funzione di stampa. Penso che sia possibile creare uno strumento per automatizzare questo. E non può essere necessariamente una funzione di stampa, ma una funzione di registrazione personalizzata. Pertanto, ogni volta che sperimentiamo una nuova funzionalità con un codice non familiare, possiamo facilmente trovare il metodo che richiama la catena per quella funzione nel registro generato dallo strumento.
smwikipedia,

64

Come mangi un elefante?

Un boccone alla volta :)

Seriamente, provo prima a parlare con gli autori del codice.


116
Come si codifica un elefante? Un byte alla volta!
Mason Wheeler,

7
il potere della comunicazione è spesso sottovalutato
poseid

17
+1 Per aver chiesto a un essere umano. E non aver paura di sembrare stupido. Racconta loro ogni ipotesi che hai fatto sul codice e ogni conclusione che hai raggiunto su come funziona e cosa fa. Ti informeranno che sei errato. Questa piccola lesione al tuo ego ti farà risparmiare così tante ore a lungo termine che i tuoi colleghi potrebbero venire a considerarti una quasi divinità.
PeterAllenWebb,

Questo ovviamente presuppone che l'autore del codice sia disponibile.
Erick Robertson,

1
@ErickRobertson ... e non è uno stronzo.
smwikipedia,

39

Devo hackerare fino a quando non ho finito il lavoro

In larga misura, sì (scusate).

Approcci che potresti prendere in considerazione:

  1. Prova a scoprire cosa dovrebbe fare il codice, in termini commerciali.
  2. Leggi tutta la documentazione esistente, non importa quanto sia grave.
  3. Parla con chiunque possa sapere qualcosa sul codice.
  4. Scorri il codice nel debugger.
  5. Introdurre piccole modifiche e vedere cosa si rompe.
  6. Apporta piccole modifiche al codice per renderlo più chiaro.

Alcune delle cose che faccio per chiarire il codice sono:

  1. Esegui un prettificatore di codice per formattare correttamente il codice.
  2. Aggiungi commenti per spiegare cosa penso possa fare
  3. Modifica i nomi delle variabili per renderli più chiari (utilizzando uno strumento di refactoring)
  4. Utilizzando uno strumento che evidenzia tutti gli usi di un particolare simbolo
  5. Riduzione del disordine nel codice: codice commentato, commenti privi di significato, inizializzazioni di variabili inutili e così via.
  6. Modifica il codice per utilizzare le convenzioni del codice corrente (utilizzando nuovamente gli strumenti di refactoring)
  7. Inizia a estrarre funzionalità in routine significative
  8. Inizia ad aggiungere test dove possibile (non spesso possibile)
  9. Sbarazzati dei numeri magici
  10. Ridurre la duplicazione ove possibile

... e qualsiasi altro semplice miglioramento tu possa apportare.

A poco a poco, il significato dietro tutto dovrebbe diventare più chiaro.

Per quanto riguarda il punto di partenza? Inizia con quello che sai. Suggerisco input e output. Spesso puoi avere un'idea di cosa dovrebbero essere e per cosa sono usati. Segui i dati attraverso l'applicazione e vedi dove vanno e come vengono modificati.

Uno dei problemi che ho con tutto ciò è la motivazione: può essere un vero slogan. Mi aiuta a pensare all'intero business come a un enigma e a celebrare i progressi che sto facendo, non importa quanto piccoli.


2
Mi piacerebbe aggiungere un po 'per questo - in termini di "hacking" - iniziare affrontando i problemi che avete ora vale a dire facendo lo sviluppo che è necessario, tutto quello che dovete capire è come fare questi cambiamenti. Imparando a conoscere lo stile del codice e a conoscerne almeno parte. Altrettanto importante, questo ti dà un focus: aggiungere questa funzione o cambiare quella funzionalità o altro. Quindi, mentre apporti la modifica, puoi eseguire i passaggi di refactoring (come descritto).
Murph,

Bella risposta. Ho avuto la situazione di entrare in un progetto che era sconosciuto per me. Ho fatto molte pulizie, comprese le fonti, il processo di creazione e così via. Immagino che non tutti i cambiamenti verranno mantenuti, ma ciò mi ha aiutato nel processo di orientamento.
Gyorgyabraham,

@Murph +1 per menzionare il focus. È molto importante tenere a mente qual è il tuo obiettivo quando hai a che fare con codebase complesse. E sì, essere appassionati di stile è altrettanto importante.
smwikipedia,

32

La tua situazione è in realtà comune. Chiunque abbia a che fare con un nuovo lavoro in cui esiste un codice esistente con cui occuparsi ne tratterà qualche elemento. Se il sistema è un sistema legacy davvero brutto, allora è molto simile a quello che hai descritto. Certo, non c'è mai alcuna documentazione attuale.

Innanzitutto, molti hanno raccomandato di lavorare in modo efficace con il codice legacy di Michael Feathers. Questo è davvero un buon libro, con capitoli utili come "Non riesco a mettere questa classe in un cablaggio di prova" o "La mia applicazione non ha struttura" sebbene a volte Feathers possa offrire solo più simpatia che soluzione. In particolare, il libro e i suoi esempi sono in gran parte orientati alle lingue delle parentesi graffe. Se stai lavorando con procedure SQL nodose potrebbe non essere altrettanto utile. Penso che il capitolo "Non capisco abbastanza bene questo codice per cambiarlo" parla del tuo problema. Feathers menziona qui le cose ovvie come prendere appunti e segnare elenchi, ma sottolinea anche che puoi eliminare il codice inutilizzato se hai il controllo del codice sorgente. Molte persone lasciano sul posto sezioni di codice commentate,

Successivamente, penso che il tuo approccio suggerito sia sicuramente un buon passo. Devi prima capire ad alto livello qual è lo scopo del codice.

Sicuramente lavora con un mentore o qualcuno del team se devi ottenere risposte alle domande.

Inoltre, cogli l'occasione per supportare il codice se vengono rilevati difetti (anche se a volte non devi offrirti volontario per questo ... il difetto ti troverà!). Gli utenti possono spiegare a cosa servono il software e in che modo il difetto li sta influenzando. Questo può essere spesso un po 'di conoscenza molto utile quando si cerca di capire il significato del software. Inoltre, entrare nel codice con un obiettivo intenzionale da attaccare a volte può aiutarti a focalizzarti di fronte a "la bestia".


13

Mi piace fare quanto segue quando ho un file sorgente molto grande:

  • Copia l'intero pasticcio negli appunti
  • Incolla in Word / textmate qualunque
  • Riduci al minimo le dimensioni del carattere.
  • Scorri verso il basso guardando gli schemi nel codice

Rimarrai sorpreso da quanto stranamente familiare il codice appare quando torni al tuo normale editor.


Questo ha iniziato a diventare più comune dal 2011 e questi sono ora diversi approcci / strumenti (li potrei trovare in questo momento ma so che esistono) che possono fornire questi contorni e conteggi di alto livello di varie cose nel codice per dare un'impressione visiva del codice, ad es. numero di righe per classe, lunghezza di ogni riga, numero medio di parametri per metodo, ecc. Questi strumenti sono ora utilizzati da manager che hanno centinaia di sviluppatori e milioni di righe di codice.
junky

Sublime Text ha una 'minimappa' che può essere utilizzata per uno scopo simile.
kmoe,

12

Richiede tempo

Non sentirti troppo affrettato mentre cerchi di capire una base di codice legacy, specialmente se utilizza tecnologie / lingue / framework che non conosci. È solo un'inevitabile curva di apprendimento che richiede del tempo.

Un approccio è andare avanti e indietro tra il codice e le esercitazioni sulle tecnologie correlate. Leggi / guarda il tutorial, poi vai a guardare il codice per vedere come hanno fatto i tuoi predecessori, notando somiglianze e differenze, prendendo appunti e ponendo domande a tutti gli sviluppatori esistenti.

"Perché hai fatto questa parte in questo modo"

"Ho notato che la maggior parte delle persone online lo fanno in questo modo, e lo avete fatto tutti in un altro modo. Perché questo?"

"Cosa ti ha fatto scegliere la tecnologia X piuttosto che la tecnologia Y?"

Le risposte a queste domande ti aiuteranno a comprendere la storia del progetto e il ragionamento alla base delle decisioni di progettazione e implementazione.

Alla fine, ti sentirai abbastanza familiare da poter iniziare ad aggiungere / riparare cose. Se tutto sembra confuso o sembra che ci sia troppa "magia" in corso, non hai trascorso abbastanza tempo a guardarlo, a digerirlo e a disegnarlo. La creazione di diagrammi (diagrammi di sequenza, diagrammi di flusso del processo, ecc.) È un ottimo modo per comprendere un processo complesso, inoltre aiuteranno il "ragazzo successivo".


9

cscope può fare tutto ciò che ctags può fare per C, inoltre, può anche elencare dove viene chiamata tutta la funzione corrente. Inoltre è molto veloce. Scala facilmente a milioni di LOC. Si integra perfettamente con emacs e vim.

Contatore di codice C e C ++ - cccc può generare metriche di codice in formato html. Ho usato anche wc per ottenere LOC.

doxygen può generare la sintassi evidenziata e il codice di riferimento incrociato in HTML. Utile nella navigazione di basi di codice di grandi dimensioni.


8

Il modo in cui raccomando con Drupal e non è proprio Drupal specifico: inizia con il tracker dei problemi. Ci saranno sicuramente vecchie segnalazioni di bug non chiuse. Puoi riprodurli? Se sì, aggiorna il ticket confermandolo. Se no, chiudilo. In questo modo troverai molti modi per utilizzare il software e puoi iniziare a sbirciare nella base di codice in cui si blocca. Oppure puoi iniziare a scorrere il codice e vedere come arriva dove si blocca. In questo modo non solo inizierai a comprendere la base di codice, ma accumulerai anche un sacco di karma e le tue domande saranno accolte calorosamente dalla comunità.


6

Una cosa importante da fare è utilizzare gli strumenti per generare grafici di dipendenza per esplorare l'architettura del codice dall'alto in basso. Visualizza prima il grafico tra gli assembly o i barattoli .NET, questo ti darà un'idea di come sono organizzate le funzionalità e i layer, quindi scava nelle dipendenze degli spazi dei nomi (all'interno di uno o alcuni assembly o barattoli relativi di .NET) per avere un'idea più fine del codice struttura e infine puoi guardare le dipendenze delle classi per capire come un insieme di classi collabora per implementare una funzione. Esistono diversi strumenti per generare il grafico delle dipendenze, ad esempio NDepend per .NET , che ha generato il grafico seguente.

inserisci qui la descrizione dell'immagine


6
Esistono innumerevoli strumenti in grado di creare grafici di dipendenze leggibili con una sorta di gerarchia, ma questo non sembra uno di questi. Lavoro anche con il design elettronico, e per questo c'è una regola empirica (letteralmente): se devo seguire una linea il tuo schema con il dito in qualsiasi momento, è un cattivo schema.

5

Una volta ho avuto un ingegnere del software piuttosto fantastico che mi diceva che la forma più costosa di analisi e manutenzione del codice era di esaminare il codice, riga per riga; ovviamente, siamo programmatori, e questo viene praticamente con il lavoro. Il mezzo felice, credo, è quello di (in questo ordine): 1. Ottenere un taccuino per creare note su come comprendere il codice per funzionare e aggiungerlo con il passare del tempo 2. Fare riferimento alla documentazione sul codice 3. Parla con autori o altri che hanno supportato la base di codice. Chiedi loro un "brain dump" 4. Se sei al punto in cui comprendi alcune delle relazioni di classe a livello di dettaglio, esegui un debug passo-passo del codice per fare una sintesi tra il modo in cui pensi che il codice funzioni e come funziona effettivamente il codice.


5

Per prima cosa, capisci cosa dovrebbe fare, senza che sia probabilmente incomprensibile. Parla con gli utenti, leggi il manuale, qualunque cosa.

Quindi premi corri e inizia a camminare per il codice per quelle che sembrano essere le funzioni chiave.


3

Dividere e conquistare. Guardo ogni funzionalità e il codice associato, passo attraverso di loro e passare alla successiva, costruendo lentamente un'immagine del tutto.

Se il progetto ha avuto dei test unitari, mi piace anche superarli, sono sempre molto rivelatori e illuminanti.


3
  1. Esegui tutti i test, se ne hai, e vedi quale codice è coperto e quali no.
  2. Se il codice che è necessario modificare non è coperto, provare a scrivere test per coprirlo.
  3. Cambia il codice. Non rompere i test.

Guarda il lavoro efficace di Michael Feathers con il codice legacy


3

Ecco la mia breve lista:

  1. Se possibile, chiedi a qualcuno di dare una visione di alto livello del codice. Quali schemi sono stati considerati, quali tipi di convenzioni potrei aspettarmi di vedere, ecc. Questo potrebbe avere qualche accenno ad esso come all'inizio avrei avuto una storia che, man mano che avrò più familiarità con il codice, potrei avere nuove domande chiedere mentre lavoro attraverso la cipolla del progetto preesistente.

  2. Esegui il codice e guarda come sono i sistemi. Concesso, potrebbe avere più di alcuni bug, ma questo può essere utile per avere un'idea di cosa fa. Non si tratta di cambiare il codice, ma piuttosto di vedere come funziona. In che modo i vari pezzi si incastrano per essere un sistema complessivo?

  3. Cerca test e altri indicatori della documentazione di base che possano aiutare a costruire un modello mentale interno del codice. È qui che probabilmente suggerirei almeno alcuni giorni a meno che non ci siano pochissime documentazioni e prove ovviamente.

  4. Conosco bene le lingue e i framework utilizzati in questo progetto? L'importanza qui è la differenza tra guardare alcune cose e dire "Sì, visto una dozzina di volte prima e conoscerlo abbastanza bene" e "Cosa nel mondo viene tentato qui? Chi pensava che fosse una buona idea?" tipo di domande che mentre non le direi ad alta voce, le penserei soprattutto se sto guardando un codice legacy che potrebbe essere abbastanza fragile e le persone che lo hanno scritto non sono disponibili o semplicemente non ricordano perché le cose sono state fatte come erano. Per le nuove aree, potrebbe essere utile dedicare un po 'di tempo extra a conoscere qual è la struttura e quali schemi posso trovare in questo codice.

Ultimo ma non meno importante: conoscere le aspettative di coloro che gestiscono il progetto in termini di cosa dovresti fare in ogni momento, date le seguenti idee su cosa ci si può aspettare:

  • Stai introducendo nuove funzionalità?
  • Stai correggendo i bug?
  • Stai refactoring codice? Le norme sono nuove per te o sono molto familiari?
  • Dovresti familiarizzare con la base di codice?

2

Cerco sempre di iniziare con il punto di ingresso nel programma, poiché tutti i programmi ne hanno uno (ad esempio metodo principale, classe principale, init, ecc.). Questo poi mi indicherà cosa inizia e talvolta come sono collegate le cose.

Dopodiché, eseguo il drill down. Il database e DAO sono configurati da qualche parte, quindi ho un'idea di come vengono archiviate le cose. Forse viene avviato anche un qualche tipo di classe di istanza globale, e lì posso capire cosa viene memorizzato. E con buoni strumenti di rifrazione, posso scoprire chi chiama cosa.

Provo quindi a trovare dove l'interfaccia è configurata e gestita, poiché questo è il prossimo punto di ingresso delle informazioni. Gli strumenti di aggiornamento, ricerca e debug sono di aiuto nella mia ricerca. Posso quindi capire dove inizia e dove finisce la gestione delle informazioni, facendomi strada attraverso tutti i file di classe.

Poi provo a scrivere il flusso su un foglio, solo per inizialmente avvolgere la mia testa intorno alle cose. Il pulsante di invio passa alla verifica generica che viene quindi passata al DAO o al database e quindi archiviata nel database. Questa è una grossolana semplificazione della maggior parte delle app, ma è l'idea generale. Penna e carta sono estremamente utili qui, poiché puoi annotare tutto rapidamente e non devi preoccuparti di formattare in un programma che avrebbe dovuto aiutarti.


2

Direi di iniziare con la documentazione, ecc., Ma nella mia esperienza, la profondità della documentazione e delle conoscenze locali è spesso inversamente proporzionale all'età, alle dimensioni e alla complessità di un sistema.

Detto questo, di solito cerco di identificare un paio di thread funzionali. Per funzionale intendo cose come il login, il pull down di un elenco di clienti, ecc. Se i pattern sono coerenti, un thread dovrebbe darti una bella e non completa sezione del sistema. Il modo migliore per determinare se i modelli sono coerenti è analizzare una manciata di thread.

Penso che sia ovvio, ma, secondo me, è meglio capire il sistema da una prospettiva funzionale piuttosto che da una prospettiva tecnica. In genere non mi preoccupo troppo degli strumenti che vengono utilizzati (ORM, librerie di registrazione, ecc.) E mi concentro maggiormente sugli schemi (MVP, ecc.) Che vengono utilizzati. Nella mia esperienza, gli strumenti sono generalmente più fluidi dei modelli.


2

Ho fatto così tanto ...

Ecco il mio approccio attuale per le situazioni in cui c'è "qualcosa che funziona" e devi farlo "funzionare in qualche altro modo".

  1. Ottieni obiettivi, quel sistema dovrebbe risolvere (se non sono stati scritti) - scrivilo. Chiedi al manager, agli altri dipendenti, anche ex, se disponibili. Chiedi al cliente o cerca qualsiasi documento.
  2. Ottieni informazioni specifiche. Se non esiste, scrivilo. Non vale la pena chiederlo a qualcuno, come se non esistesse, allora ti trovi in ​​una situazione in cui agli altri non importa molto. Quindi l'unico modo per scrivere il proprio (in seguito sarà molto più facile fare riferimento ad esso).
  3. Ottieni design. Non esiste: scrivilo. Prova a fare riferimento a qualsiasi documento e codice sorgente il più possibile.
  4. Scrivi un disegno dettagliato alla parte che devi modificare.
  5. Definisci come testarlo. Quindi potresti essere sicuro che il vecchio e il nuovo codice funzionano allo stesso modo.
  6. rendere il sistema in grado di essere costruito in un solo passaggio. E prova con il vecchio codice. Mettilo in SVC se non lo è già.
  7. Implementare le modifiche. Non prima.
  8. verificare dopo circa un mese che nulla sia rotto.

Un altro todo facoltativo che potrebbe essere necessario tra ogni passaggio: f off manager (proprietario del progetto) che ti dice che "questi cambiamenti dovrebbero essere fatti già ieri". Dopo alcuni progetti, potrebbe persino iniziare ad aiutare a ottenere in anticipo specifiche e documenti.

Ma di solito (specialmente per gli script) non è possibile nell'ambito del business (il costo sarà troppo elevato, mentre il valore sarà troppo basso). Un'opzione è quella di non apportare modifiche, fino a quando non viene raggiunta la massa critica, e il sistema si spegne dalla produzione (ad es. Arriverà un nuovo sistema) o la direzione ha deciso che vale la pena fare tutto questo.

PS: ricordo un codice utilizzato per 5 client con impostazioni diverse. E ogni modifica (nuova funzionalità) era necessaria pensando a "quali parti vengono utilizzate" e "quali client di configurazione hanno" in modo da non frenare nulla e non copiare il codice. Mettere le loro impostazioni per proiettare CV e scrivere specifiche riduce questo tempo di riflessione quasi a 0.


2
Mi dispiace, non credo che riuscire a far decadere un manager o un project manager in un nuovo lavoro funzionerà bene per te. Sono stato nella stessa identica situazione e tutte le persone a cui teniamo all'inizio sono risultati, risultati, risultati. Produci risultati e poi hai la possibilità di cambiare idea, perché ora sanno che sei un lavoratore capace capace di fare il lavoro. Suggerisci miglioramenti e potresti essere ascoltato. Non viceversa, verrai licenziato prima della fine del periodo di prova.
Andre,

1
Ci sono molti modi per farlo educatamente. Ad esempio, scrivere una stima secondo la quale le modifiche dirette richiederanno 30 ore e un'altra stima secondo questo piano: 50 ore. Nel secondo caso avere obiettivi, specifiche e design farà risparmiare molto tempo per cambiamenti futuri. Se il manager non è disposto a capire, molto probabilmente non sarai in grado di cambiarlo in futuro e lavorerai permanentemente con le palle di fango. Può essere un buon indicatore trovare un altro lavoro allora? Se accetta il piano, allora mostragli dove sei, quando chiede "risultati, risultati, risultati".
Konstantin Petrukhnov,

2

Stampa il codice sorgente e inizia a leggerlo. Se è particolarmente grande, stampa solo parti selezionate per capirlo meglio e prendere tutte le note / i commenti di cui hai bisogno.

Traccia attraverso il programma a partire dall'inizio della sua esecuzione. Se si è assegnati a una parte particolare della base di codice, tracciare l'esecuzione all'interno di quella parte e capire quali strutture di dati vengono utilizzate.

Se stai usando un linguaggio orientato agli oggetti, prova a creare un diagramma di classe generale. Questo ti darà una buona panoramica di alto livello.

Sfortunatamente, alla fine, dovrai leggere più codice possibile. Se sei fortunato, i programmatori precedenti hanno scritto quanta più documentazione possibile per aiutarti a capire cosa sta succedendo.


2

La prima cosa che devi fare quando impari una nuova base di codice è imparare cosa dovrebbe fare, come viene usato e come usarlo. Quindi iniziare a consultare la documentazione architettonica per apprendere come è strutturato il codice, inoltre osservare come il database a questo punto. Allo stesso tempo stai imparando l'architettura è un buon momento per rivedere tutti i flussi di processo o utilizzare i documenti del caso. quindi inizia a immergerti e a leggere il codice dopo aver compreso il quadro generale, ma solo il codice relativo a qualsiasi lavoro che potresti svolgere su questo codice, non limitarti a leggere tutto il codice. È più importante sapere dove deve fare il codice X piuttosto che esattamente come viene fatto X, il codice è sempre lì per dirti come se riesci a trovarlo.

Trovo che il solo tentativo di saltare e leggere il codice senza un obiettivo oltre l'apprendimento del codice sia generalmente improduttivo, cercare di apportare piccole modifiche da soli o rivedere il codice delle modifiche di qualcun altro è un uso molto più produttivo del tuo tempo.


2

Se una base di codice è grande, focalizza la tua attenzione sulle parti su cui si sta attualmente lavorando. Altrimenti ti sentirai sopraffatto e forse la tua testa potrebbe esplodere. Penso che una panoramica di alto livello sia utile (se disponibile), ma è probabile che trascorrerai molto tempo nel debugger per seguire il flusso del programma. È una buona idea avere una panoramica dell'applicazione e vederla utilizzata, in modo da poter capire come / cosa / perché il codice viene utilizzato.

Di solito eseguo una sorta di strumento di complessità del codice sul codice per dirmi dove si trovano le aree problematiche. Le aree con un punteggio elevato sono probabilmente molto difficili da aggiornare. Ad esempio, mi sono imbattuto in una funzione che ha segnato 450 sulla scala ciclomatica. Abbastanza sicuro, centinaia di IF. Molto difficile da mantenere o cambiare. Quindi preparati al peggio.

Inoltre, non abbiate paura di porre domande agli sviluppatori esistenti, specialmente se hanno lavorato sul sistema. Tieni i tuoi pensieri interni per te stesso e concentrati sulla risoluzione dei problemi. Evita i commenti che potrebbero far arrabbiare gli altri sviluppatori. Dopo tutto, potrebbe essere il loro bambino e a nessuno piace sentirsi dire che il loro bambino è brutto.

Fai piccoli passi, anche la più piccola modifica del codice può avere un grande impatto.

Trovo che sia utile elaborare flussi di codice di programma, quindi se sto apportando modifiche, posso fare ricerche di dipendenza per vedere quali metodi / funzioni chiamano cosa. Supponiamo che sto cambiando metodo C.

Se solo 1 metodo / funzione chiama C, allora è un cambiamento abbastanza sicuro. Se 100s di metodi / funzioni chiamano C, allora avrebbe un impatto maggiore.

Spero che la tua base di codice sia ben progettata, scritta e mantenuta. In tal caso, ci vorrà del tempo per capirlo, ma alla fine la marea verrà cambiata.

Se è una grande palla di fango, potresti non capire (o voler capire) il suo funzionamento interiore.


2

Alcune cose che faccio ...

1) Utilizzare uno strumento di analisi della sorgente come Source Monitor per determinare le varie dimensioni del modulo, le metriche di complessità ecc. Per farsi un'idea del progetto e aiutare a identificare le aree non banali.

2) Esplorare il codice dall'alto verso il basso in Eclipse (buono per avere un editor in grado di sfogliare i riferimenti, ecc.) Fino a quando non so cosa sta succedendo e dove nella base di codice.

3) Occasionalmente, disegno diagrammi in Visio per ottenere una migliore immagine dell'architettura. Questo può essere utile anche per gli altri nel progetto.


1

Questo succede molto. Fino a quando non ho iniziato a lavorare su una piattaforma open source, non credo di aver mai iniziato un lavoro che non ha avuto inizio con l'ammissione che il codice aveva alcune "stranezze".

Puoi fare molta strada con un debugger step e molta tenacia. Sfortunatamente spesso ci vuole tempo ed esperienza per imparare una particolare grande palla di fango e anche allora, dopo anni, può ancora esserci un sottosistema che emerge, di cui nessuno è a conoscenza.


1

Ti incoraggio a scrivere test unitari prima di cambiare qualcosa nella sfera di fango. E cambia solo abbastanza codice al momento per far passare i test. Mentre esegui il refactoring, aggiungi prima i test unitari in modo da sapere che la funzionalità di business non è stata eliminata dal refactoring.

La programmazione delle coppie è un'opzione? Avere un'altra persona per far rimbalzare le idee è un'ottima idea per affrontare quella quantità di cattivi.


Uno dei problemi di una Big Ball of Mud è che non ha limiti adeguati per scrivere test unitari. Una volta arrivato al punto in cui puoi testare correttamente l'unità, hai praticamente vinto.
Donal Fellows il

Ma, se stai iniziando a modificare il codice, dovresti comunque disporre di unit test in modo da sapere quando hai completato la correzione.
David Weiser,

1

Ecco una procedura che usiamo per eliminare i duplicati.

  • selezionare un prefisso di commento standard per i duplicati (usiamo [dupe]subito dopo l'indicatore di commento;
  • scrivere specifiche con i propri team sui nomi da utilizzare per la procedura duplicata;
  • primo round: tutti prendono alcuni file e li aggiungono [dupe][procedure_arbitrary_name]prima della procedura duplicata;
  • secondo round: ognuno prende una procedura o un sottoinsieme di procedura e assegna un valore che indica l'ordine di simpatia delle diverse implementazioni dello stesso scopo (la stringa sarà quindi:) [dupe][procedure_arbitrary_name][n];
  • terzo round: il responsabile di ciascuna procedura lo riscrive nella relativa classe;
  • quarto round: grepfelice!

1

Penso che una delle cose più importanti sia prendere una funzione semplice, scegliere la più semplice a cui puoi pensare e implementarla. Se esiste una lista dei desideri mantenuta, usa quella o parla con qualcuno che ha familiarità con la base di codice e induci a suggerire una funzione. Di solito mi aspetto che questo sia un cambiamento con 5 ~ 20 LOC. Il punto importante non è che stai aggiungendo una funzionalità molto sofisticata, ma che stai lavorando (o piuttosto afferrando :)) con la base di codice e attraversando l'intero flusso di lavoro. Dovresti

  1. Leggi il codice per capire il componente che stai modificando
  2. Cambia codice e comprendi come questo influisce sul sistema circostante.
  3. Testare la modifica e quindi identificare il modo in cui i componenti interagiscono tra loro
  4. Scrivi il caso di test e, si spera, rompi uno o due casi di test in modo da riuscire a risolverli e comprendere gli invarianti del sistema.
  5. Costruisci la cosa o vedi il CI costruirla e poi spedirla

L'elenco continua, ma il punto è che un mini progetto come questo ti guida attraverso tutti gli elementi della tua lista di controllo per conoscere un sistema e comporta anche un cambiamento produttivo.


1

Una piccola cosa che volevo aggiungere:

Uno strumento che ho iniziato a utilizzare di recente per questo tipo di problema che ha aiutato immensamente è la mappatura mentale. Invece di provare a riempire tutti i dettagli di come qualcosa è implementato nella mia testa, costruirò una mappa mentale che descrive come funziona il sistema che sto attraversando. Mi aiuta davvero a comprendere meglio cosa sta succedendo e cosa devo ancora capire. Mi aiuta anche a tenere traccia di ciò che devo cambiare su una scala molto precisa.

Raccomando di usare il piano libero tra la pletora di scelte di mappatura mentale.


1

Non ci sarà documentazione o documentazione scarsa o non sarà aggiornata. Trova tutta la documentazione esistente. Se si trova in un repository di team, non crearne una copia. In caso contrario, mettilo lì e chiedi al tuo manager l'autorizzazione per organizzarlo, magari con un po 'di supervisione.

Ottieni tutto nel repository per il team e aggiungi un Glossario. Tutte le basi hanno il gergo; documentalo nel glossario. Crea sezioni per strumenti, prodotti, specifici per il cliente, ecc.

Crea / Aggiorna un documento di creazione di un ambiente software. Tutti gli strumenti, le stranezze, le opzioni di installazione, ecc. Vanno qui.

Quindi carica un documento Guida introduttiva a "ProductName" o simili. Lascia che sia solo flusso di mente e auto-organizzazione nel tempo. Quindi consulta i documenti non aggiornati e ripristinali. Gli altri sviluppatori lo apprezzeranno, contribuirai in un modo unico durante l'apprendimento del codice. Soprattutto documenta tutte quelle cose che ti mettono in imbarazzo o che hanno un nome sbagliato o sono contro-intuitive.

Una volta terminata la curva di inclinazione, non preoccuparti di aggiornare la documentazione. Lascia che il nuovo ragazzo lo faccia. Quando arriva, indicalo al tuo lavoro. Quando ti infastidisce continuamente per le risposte, non rispondergli. Piuttosto, aggiungi la domanda alla tua documentazione e poi consegnagli l'URL. Canna da pesca.

Un effetto collaterale è che avrai creato uno strumento a cui puoi fare riferimento da solo mesi a quando ti dimentichi.

E sebbene non si tratti di documentazione, un problema correlato sono tutte le piccole procedure strane e manuali che i tuoi compagni di squadra fanno. Automatizzali con batch, script sql e simili, e condividi anche quelli. Dopotutto, la conoscenza procedurale è probabilmente grande quanto la conoscenza dichiarativa in termini di produttività in un nuovo ambiente. Qualunque cosa sia, non farlo; piuttosto, scrivilo ed eseguilo. La canna da pesca colpisce ancora.


1

Ho scritto un post abbastanza lungo su questo argomento. Ecco un estratto

Ho pensato a questo problema per un po '. Ho deciso di scrivere la mia soluzione personale come processo generale. I passaggi che ho documentato sono i seguenti:

  1. Crea foglio di vocabolario
  2. Scopri l'applicazione
  3. Sfoglia la documentazione disponibile
  4. Fai ipotesi
  5. Individua le librerie di terze parti
  6. Analizza codice

Questo processo è scritto nel contesto di un'applicazione desktop di grandi dimensioni, ma le tecniche generali sono ancora applicabili alle applicazioni Web e ai moduli più piccoli.

tratto da: Un processo per l'apprendimento di una nuova base di codice


1

Ci sono alcuni piccoli consigli che posso condividere.

Per un prodotto esistente, inizio a testarli intensamente. Se scegli / ricevi un'attività, mi concentrerò maggiormente su quella particolare funzione.

  • Il prossimo passo sarebbe trovare il codice in cui posso entrare e iniziare a esplorare. Sulla strada troverò i moduli dipendenti, le librerie, i framework ecc.

  • Il prossimo passo sarebbe creare un semplice diagramma di classe con le sue responsabilità (come le carte CRC)

  • Inizia a apportare modifiche minori o accetta bug minori per correggere e eseguire il commit. In questo modo possiamo apprendere il flusso di lavoro del progetto; non solo il codice. Spesso i prodotti di grandi dimensioni avranno una sorta di contabilità a fini di autorizzazione e audit (ad es. Progetti sanitari)

  • Parla con le persone che stanno già lavorando al progetto. Esprimi le tue idee, i tuoi pensieri e in cambio ottieni la loro esperienza e opinioni sul lavoro con questo progetto per molto tempo. Questo è abbastanza importante perché ti aiuta anche ad andare d'accordo con la squadra.


1

È passato molto tempo da quando ho dovuto immergermi in una grande base di codici da solo. Ma negli ultimi due anni ho provato molte volte a coinvolgere nuovi sviluppatori in team in cui disponevamo di una base di codice esistente, piuttosto ampia.

E il metodo che abbiamo usato con successo, e direi che è il modo più efficace senza dubbio IMHO, è la programmazione di coppie.

Negli ultimi 12 mesi, abbiamo avuto 4 nuovi membri nel team e ogni volta, il nuovo membro si accoppiava con un altro membro che conosceva bene la base di codice. All'inizio, il membro del team più anziano avrebbe la tastiera. Dopo circa 30 minuti passeremmo la tastiera al nuovo membro, che lavorerebbe sotto la guida del membro del team più anziano.

Questo processo ha dimostrato di avere abbastanza successo.


Sì, posso vedere che una finestra di dialogo tra due persone e una base di codice può essere molto utile. Il dialogo ti costringe a pensare ad alta voce, che altrimenti potrebbe rimanere una sorta di presupposto.
Miku,
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.