Come rendere più comprensibile un grande codebase per i nuovi programmatori

102

Supponiamo che io stia sviluppando un progetto relativamente grande. Ho già documentato tutte le mie classi e funzioni con Doxygen, tuttavia, ho avuto l'idea di inserire una "nota del programmatore" su ciascun file di codice sorgente.

L'idea alla base di questo è di spiegare in parole povere come una classe specifica funziona (e non solo perché come fanno la maggior parte dei commenti). In altre parole, per dare agli altri programmatori una visione alternativa di come funziona una classe.

Ad esempio:

/*
 * PROGRAMMER'S NOTES:
 *
 * As stated in the documentation, the GamepadManager class 
 * reads joystick joystick input using SDL and 'parses' SDL events to
 * Qt signals.
 *
 * Most of the code here is about goofing around the joystick mappings.
 * We want to avoid having different joystick behaviours between
 * operating systems to have a more integrated user experience, since
 * we don't want team members to have a bad surprise while
 * driving their robots with different laptops.
 *
 * Unfortunately, we cannot use SDL's GamepadAPI because the robots
 * are interested in getting the button/axes numbers, not the "A" or
 * "X" button.
 *
 * To get around this issue, we created a INI file for the most common 
 * controllers that maps each joystick button/axis to the "standard" 
 * buttons and axes used by most teams. 
 *
 * We choose to use INI files because we can safely use QSettings
 * to read its values and we don't have to worry about having to use
 * third-party tools to read other formats.
 */

Sarebbe un buon modo per rendere più semplice un grande progetto per i nuovi programmatori / contributori per capire come funziona? Oltre a mantenere uno stile di codifica coerente e un'organizzazione di directory "standard", ci sono "standard" o raccomandazioni per questi casi?

    
posta Alex Spataru 01.08.2015 - 00:33
fonte

10 risposte

135

Questo è fantastico. Vorrei che più sviluppatori di software si siano presi il tempo e gli sforzi per farlo. E:

  • Dichiara in inglese semplice ciò che fa la classe (cioè è responsabilità),
  • Fornisce utili informazioni supplementari sul codice senza ripetere testualmente ciò che il codice già dice,
  • Delinea alcune delle decisioni di progettazione e il motivo per cui sono state create e
  • Mette in evidenza alcuni dei trucchi che potrebbero accadere alla prossima persona che legge il tuo codice.

Ahimè, molti programmatori cadono nel campo di "se il codice è scritto correttamente, non dovrebbe essere documentato". Non vero. Esistono molte relazioni implicite tra classi di codici, metodi, moduli e altri artefatti che non sono ovvi solo leggendo il codice stesso.

Un programmatore esperto può creare con cura un progetto con un'architettura chiara e facilmente comprensibile, ovvia senza documentazione. Ma quanti programmi hai visto?

    
risposta data 01.08.2015 - 00:42
fonte
35

La chiave per lavorare con un codebase di grandi dimensioni non è la necessità di leggere l'intero codebase per apportare modifiche. Per consentire a un programmatore di trovare rapidamente il codice che sta cercando, il codice dovrebbe essere organizzato e l'organizzazione apparente. Cioè, ogni unità logica nel codice, dall'eseguibile, dalla libreria, dallo spazio dei nomi, fino alla classe individuale dovrebbe avere una responsabilità chiaramente evidente. Pertanto non mi limiterei a documentare i file sorgente, ma anche le directory in cui risiedono.

Le note del tuo programmatore forniscono anche informazioni sulle decisioni di progettazione. Sebbene questa possa essere un'informazione preziosa, la separerei dall'affermazione di responsabilità (per consentire al lettore di scegliere se leggere la responsabilità della classe o il suo fondamento logico) e spostarla il più vicino possibile alla fonte che descrive possibile, per massimizzare la possibilità che la documentazione sia aggiornata quando il codice è (la documentazione è utile solo se possiamo fidarci della sua accuratezza - la documentazione obsoleta può essere peggiore di nessuna!).

Detto questo, la documentazione dovrebbe rimanere ASCIUTTA, cioè non ripetere informazioni che potrebbero essere state espresse in codice o già descritte altrove (frasi come "come afferma la documentazione" sono un segnale di avvertimento). In particolare, i futuri manutentori saranno solo abili nel linguaggio di programmazione del progetto così come sono in inglese; Parafrasando l'implementazione nei commenti (che vedo troppo spesso quando le persone sono orgogliose della loro documentazione) non ha alcun beneficio, ed è probabile che diverga dall'implementazione, in particolare se la documentazione non è vicina al codice che descrive.

Infine, la struttura della documentazione dovrebbe essere standardizzata in tutto il progetto in modo che tutti possano trovarla (è un disordine reale dei documenti di Peter nel bug tracker, Sue nel wiki, Alan nel readme e John nel codice sorgente. ..).

    
risposta data 01.08.2015 - 11:26
fonte
13

Non sono d'accordo, questo è un approccio molto buono, principalmente dovuto a

  1. Quando rifattori il tuo progetto, sposta i metodi, interrompe la documentazione.

  2. Se la documentazione non viene aggiornata correttamente, risulterà in una maggiore confusione di quella che aiuta a capire il codice.

Se si dispone di test unitari per ogni metodo / test di integrazione per ciascun modulo, sarebbe un'auto-documentazione più manutenibile e più facile da capire rispetto ai commenti del codice.

Sì, avere una struttura di directory adeguata sicuramente aiuterà.

    
risposta data 02.08.2015 - 11:55
fonte
7

Personalmente sono un fan di un documento di design di alto livello - preferibilmente scritto PRIMA di qualsiasi codice - che offre una panoramica del design e un elenco di classi e risorse. Un design top-down semplifica enormemente le cose: il tuo potrebbe essere "motore di gioco - > hardware - > controller - > joystick"; quindi, un nuovo programmatore ha detto "aggiustare il pulsante" a "sul" controller xyz "almeno saprebbe dove iniziare a cercare.

Troppi linguaggi moderni tendono a violare il codice in centinaia di piccoli file, quindi trovare il file corretto può essere una sfida anche per un progetto moderato.

    
risposta data 01.08.2015 - 10:58
fonte
5

Se la base di codice è ampia, provo a fornire un documento di design che delinea gli elementi chiave del suo design e l'implementazione . L'intenzione qui non è di dettagliare nessuna delle classi utilizzate, ma fornire una chiave per il codice e il pensiero che è andato nel design. Fornisce un contesto generale al sistema, ai suoi componenti e alla relativa applicazione.

Le cose da includere nel documento di progettazione sono;

  • Architettura dell'applicazione
  • Struttura del codice logico
  • Flussi di dati
  • I pattern chiave utilizzati e la motivazione dietro il loro utilizzo
  • Struttura sorgente del codice
  • Come costruirlo (questo offre informazioni sulle dipendenze implicite e sulla struttura fisica del codice sorgente)

Di seguito, la documentazione per le classi e le funzioni / i metodi dovrebbero essere completati come appropriato . In particolare l'API pubblica; dovrebbe essere chiaro quali sono i seguenti in ogni caso;

  • Presupposti
  • Effetti
  • invarianti
  • Condizioni di eccezione (tiri)
risposta data 03.08.2015 - 11:02
fonte
4

La regola più importante che ho trovato per rendere più semplice per i nuovi sviluppatori la comprensione di un codebase è un accordo perfetto è costoso.

Se i nuovi sviluppatori devono comprendere perfettamente il sistema su cui stanno lavorando, prevengono tutte le opportunità per l'apprendimento del lavoro. Penso che le note del programmatore siano un ottimo inizio, ma vorrei andare oltre. Prova a scrivere un codice che, se si avvicina di nuovo, consentirebbe a uno sviluppatore di capire cosa stanno facendo al volo, piuttosto che richiedere loro di imparare prima di farlo. Piccole cose come affermazioni per casi che sai non possono mai accadere, insieme a commenti che spiegano perché l'affermazione è valida, fatti di strada. Così scrive codice che fallisce con garbo piuttosto che segfaulting se fai qualcosa di sbagliato.

    
risposta data 02.08.2015 - 08:51
fonte
3

Ho visto grandi classi con la documentazione, e dopo aver letto la documentazione non ho idea di cosa questa classe dovrebbe essere buona e perché qualcuno la userebbe! Allo stesso tempo, avevo bisogno di alcune funzionalità e ero assolutamente sicuro che ci fosse una classe per gestirlo, e non potevo trovarlo da nessuna parte - perché non c'era documentazione che mi portasse da quello che avevo bisogno della classe facendolo.

Quindi la prima cosa che vorrei nella documentazione è solo alcune frasi che cosa fa una classe, e perché vorrei usarla. I commenti nella domanda originale stanno andando abbastanza bene a tale riguardo. Dopo aver letto questi commenti, se avessi un joystick che non funziona bene perché non riesco a interpretare i valori che fornisce, vorrei sapere quale codice controllare.

    
risposta data 02.08.2015 - 22:21
fonte
0

Simile a ciò che @meriton ha detto, suddividere il codice in componenti separati. Ancora meglio, abbattere il codice in pacchetti separati (JAR, gemme, uova, qualunque cosa) per rendere ancora più chiaro come i componenti siano separati. Se c'è un bug, uno sviluppatore deve solo trovare il pacchetto dove si trova il bug e (si spera) risolverlo solo lì. Per non parlare del fatto che è più facile eseguire il test delle unità e sfruttare la gestione delle dipendenze.

Un'altra soluzione: rendere il codebase più piccolo. Meno codice c'è, più facile è capire. Rif. Codice inutilizzato o duplicato. Utilizza tecniche di programmazione dichiarativa . Questo richiede uno sforzo, ovviamente, e spesso non è possibile né pratico. Ma è un obiettivo degno. Come ha scritto Jeff Atwood: Il miglior codice non è affatto un codice

    
risposta data 08.08.2015 - 16:39
fonte
-1

Per sistemi complessi può valere la pena non solo documentare ogni file, ma le loro interazioni e gerarchia, e come il programma si struttura e perché.

Ad esempio un motore di gioco di solito è piuttosto complesso ed è difficile decidere cosa chiama dopo cento strati di astrazione. Potrebbe valere la pena di creare un file come "Architecture.txt" per spiegare come e perché il codice è strutturato in questo modo, e perché c'è uno strato di astrazione dall'aspetto inutile lì.

    
risposta data 02.08.2015 - 13:25
fonte
-7

Questo può essere in parte perché è difficile per un singolo programmatore scriverlo, poiché ogni individuo comprende solo la propria parte di progetto.

A volte puoi ottenere queste informazioni dalle note del project manager, ma questo è tutto ciò che otterrai, poiché raramente riscrivono le loro note in questo formato.

    
risposta data 01.08.2015 - 07:17
fonte

Leggi altre domande sui tag