Qual è il modo di capire il codice spaghetti gigante non commentato di qualcun altro? [duplicare]

9

Recentemente ho gestito un gigantesco programma multithread senza commenti e mi è stato chiesto di capire cosa fa, e quindi di migliorarlo (se possibile).

Ci sono delle tecniche che dovrebbero essere seguite quando abbiamo bisogno di capire il codice di qualcun altro? O partiamo subito dalla prima chiamata di funzione e continuiamo a tracciare le chiamate di funzione successive?

C ++ (con multi-threading) su Linux

    
posta Aquarius_Girl 06.11.2012 - 09:36
fonte

9 risposte

7

Dipenderà dalla lingua, ma (e so che è uno strumento terribilmente vecchio stile) IMHO non puoi battere un semplice diagramma di flusso per il codice, con il diagramma del flusso di dati associato.

Praticamente il modo in cui uno avrebbe progettato il codice dai requisiti, in passato.

Inizia dall'intero programma e decomponi ...

Ovviamente, farai una tabella separata per ogni funzione (non banale) ... il dettaglio di ciascun grafico dipende dalla complessità funzionale.

Nel caso delle classi, considera ogni classe come un blocco autonomo autonomo - da un punto di vista di sistema, ogni classe dovrebbe (se progettata correttamente) essere considerata una "scatola nera"

Decomponi l'intero in classi, poi le classi in strutture e funzioni dati, ecc.

Gli strumenti moderni come l'UML hanno il loro posto, ma per il reverse engineering, attenersi agli strumenti di base.

    
risposta data 06.11.2012 - 09:47
fonte
3

Sarebbe molto utile se ci fossero alcuni test unitari attorno al codice - i test di unità possono spesso avere una funzione secondaria come documentazione.

Tuttavia, il codice legacy viene spesso senza test. Magari scrivere alcuni sarebbe un buon modo per capire cosa sta succedendo?

Quindi, puoi rifattorizzare il codice spaghetti in un codice facile da leggere e ben scritto.

    
risposta data 06.11.2012 - 14:19
fonte
3

Fondamentalmente, vuoi seguire il metodo scientifico . osservare, ipotizzare, testare. Ci sono varie tecniche che potrebbero essere appropriate per ogni fase.

Osservare:

  1. Esegui il codice: si spera, questo è ovvio!
  2. Esegui il codice attraverso un profiler: questo può essere un buon indicatore di dove concentrare i tuoi sforzi. Se si dispone di un profiler decente, può anche essere utile per rilevare gli effetti collaterali imprevisti delle operazioni.
  3. Scorri il codice in un debugger: abbastanza cruciale se stai cercando di capire i dettagli.

ipotizzare:

  1. I diagrammi di flusso possono essere utili per costruire le tue ipotesi: possono essere molto utili per chiarire cosa sta facendo una funzione / etc. Ricorda che se il codice che devi rappresentare è simile agli spaghetti, allora anche i tuoi diagrammi di flusso saranno inevitabili!
  2. Modifica il codice: aggiungi un commento al codice, forza il valore di una variabile, inserisci chiamate di metodo aggiuntive, ecc. ecc.
  3. Scrivi test unitari: dovrebbero essere un po 'meno ad-hoc rispetto alle modifiche rapide del codice. usali quando sei più sicuro delle tue ipotesi. Hanno il vantaggio aggiunto, come afferma Paul T Davies, di essere estremamente utile quando si tratta di qualsiasi futuro refactoring.

Prova:

Esegui i test di codice / unità modificati e osserva di nuovo! Se avevi ragione, documentalo (commenti, ecc.) E passa alla prossima cosa (che può essere riordinare / refactoring del codice). Altrimenti, crea nuove ipotesi basate sui tuoi nuovi dati.

    
risposta data 06.11.2012 - 15:31
fonte
2

Potresti trovare aiuto nelle risposte a questa domanda StackOverflow: link

    
risposta data 06.11.2012 - 14:40
fonte
2

Ciò che ha funzionato per me è:

  • Crea una copia della sorgente e un ambiente di test (ad esempio una copia del database) in modo da poter scherzare senza causare alcun danno.

  • Refactor , estraendo a una funzione / metodo / script ogni blocco di codice ripetitivo (o non ripetitivo) che hai capito abbastanza bene e abbastanza sicuro. In questo modo prenderai lontano dalla vista tutto ciò che già comprendi, poco ingombrante ciò che non fai.

  • Puoi stampare determinati pezzi di codice lungo per poterli studiare su carta. Questo aiuta, non so perché, forse perché puoi buttare frecce e cerchi attorno alle cose.

  • Ciò che avrai alla fine è una versione più breve, ordinata e refactored del codice. Non ti sto dicendo che tu sostituisci il codice di produzione con quello refactored (dipende da te). Ma il processo di refactoring in un ambiente sicuro ti ha aiutato a capire la versione di produzione ancora disordinata.

risposta data 06.11.2012 - 15:18
fonte
2

Non è un compito facile, ma ... potrebbe essere uno strumento di documentazione come doxygen , anche se applicato a un codice non documentato, ca fai un buon inventario di spazi dei nomi, classi, funzioni, il modo in cui interagiscono tra loro, come si fanno riferimento l'un l'altro e così via.

Non spiega cosa fa tutto, ma almeno aiuta a iniziare a capire come è composto il codice. Almeno mantiene ordinati gli spaghetti!

    
risposta data 06.11.2012 - 15:03
fonte
1

IMO uno dei modi più rapidi per arrivare al fondo del codice non familiare è rintracciare lo / gli sviluppatore / i originale (ad esempio su Linked-In) e stabilire un contatto, ponendo alcune domande di alto livello (potrebbe essere necessario inviare alcuni snippet di codice per fare jog sulla sua memoria). Ovviamente avrai bisogno di sorvolare i tuoi reali sentimenti verso la qualità del codice.

La maggior parte degli sviluppatori che conosco di solito sono ragionevolmente orgogliosi del loro lavoro (giustificato o meno) e sono troppo felici di divulgare le conoscenze sui loro sistemi precedenti (inoltre, la motivazione è che il colpevole probabilmente guadagna da vivere come sviluppatore nello stesso stato / città, è probabile che voglia mantenere la sua reputazione intatta).

Se il precedente dev è in grado di trasmettere alcuni dei modelli concettuali (o anti-pattern) che hanno utilizzato, può aiutarti ad aiutarti rapidamente ad aprire la maggior parte della base di codice.

E anche se non riesci a rintracciare lo sviluppo, o non ottenere risposta, prendendo tempo per formulare una domanda ("Perché hai fatto X qui?"), potrebbe portare il tuo processo di pensiero verso una soluzione.

    
risposta data 06.11.2012 - 14:53
fonte
0

Vorrei iniziare con i test di sistema solo per vedere cosa fa il programma e quindi collegarlo a brevi diagrammi di flusso per mostrare come fa ciò che fa. Solo i test di sistema ti permettono di capire che cosa il sistema non fa come fa e i diagrammi di flusso tendono a darti un aspetto piuttosto astratto del sistema e può richiedere un po 'di tempo per poter dire cosa fa effettivamente il pulsante x quindi è meglio per usarli insieme IMO.

    
risposta data 06.11.2012 - 14:42
fonte
0

Il modo più veloce e più istruttivo per imparare una nuova base di codice, che sia elegante o spaghetti, e quando non hai risorse come documentazione o persone esperte da chiedere, è di cambiare qualcosa. Questo potrebbe anche essere un cambiamento nella direzione delle esigenze del business. Ma tieni una piccola modifica all'inizio.

Il refactoring di qualcosa di piccolo è un buon modo per iniziare. Per esempio. una classe che sembra avere un comportamento "tacked-on" (ad esempio una classe che gestisce la gestione di alcuni dati, ma scrive anche tali dati in un formato di file) e la tiene in un sottomodulo (che scrive i dati dati nel formato richiesto ). Rimuovere il codice è divertente: cerca di eliminare una variabile globale o elimina una variabile membro che può essere locale. Cerca di eliminare un'intera classe che sembra fare molto poco per le linee di codice che occupa.

Se il codice non è commentato, non si tratta necessariamente di una perdita totale. Può essere che i nomi delle variabili siano stati scelti bene. Altrimenti, avrai del lavoro extra da fare. Rinomina le variabili seguendo la tua convenzione di denominazione che ha senso e non aver paura di usare nomi di variabili lunghi. Ci sono molte opinioni sulla denominazione delle variabili, ma penso sempre "capisci il senso, non scrivi". Rinominare le variabili con un nome errato ti costringerà a capire a cosa serve ogni variabile (che è qualcosa che l'autore originale era troppo pigro per fare).

Come compito di per sé , disegnare diagrammi di ciò che pensi sta succedendo è una perdita di tempo ed è solo una diversione da ciò che devi fare che è, e non c'è modo di allontanarsi da questo, leggere il codice. Può essere meglio incollare piccoli estratti di codice da classi e moduli diversi in un documento di testo e descrivere cosa sta succedendo in quel modo. Potrebbe essere necessario fare diagrammi in seguito per chiarire le cose ad alto livello o per aiutare a spiegare il codice a qualcun altro. Spiegare il codice a qualcun altro è un buon modo per aumentare la tua comprensione.

Questi suggerimenti sono già stati fatti: scrivere test di unità e contattare l'autore precedente sono sicuramente una parte dell'attacco di una base di codice ereditata.

    
risposta data 06.11.2012 - 15:37
fonte

Leggi altre domande sui tag