I commenti XML sono necessari documentazione?


10

Ero un fan del richiedere commenti XML per la documentazione. Da allora ho cambiato idea per due motivi principali:

  1. Come il buon codice, i metodi dovrebbero essere autoesplicativi.
  2. In pratica, la maggior parte dei commenti XML sono rumori inutili che non forniscono alcun valore aggiuntivo.

Molte volte usiamo semplicemente GhostDoc per generare commenti generici, e questo è ciò che intendo per rumore inutile:

    /// <summary>
    /// Gets or sets the unit of measure.
    /// </summary>
    /// <value>
    /// The unit of measure.
    /// </value>
    public string UnitOfMeasure { get; set; }

Per me è ovvio. Detto questo, se ci fossero istruzioni speciali da includere, dovremmo assolutamente usare i commenti XML.

Mi piace questo estratto di questo articolo :

A volte, dovrai scrivere commenti. Ma dovrebbe essere l'eccezione non la regola. I commenti devono essere usati solo quando esprimono qualcosa che non può essere espresso nel codice. Se vuoi scrivere un codice elegante, cerca di eliminare i commenti e scrivi invece un codice autocompattante.

Sbaglio pensando che dovremmo usare i commenti XML solo quando il codice non è abbastanza per spiegarsi da solo?

Credo che questo sia un buon esempio in cui i commenti XML rendono il codice piuttosto brutto. Ci vuole una classe come questa ...

public class RawMaterialLabel : EntityBase
{
    public long     Id                      { get; set; }
    public string   ManufacturerId          { get; set; }
    public string   PartNumber              { get; set; }
    public string   Quantity                { get; set; }
    public string   UnitOfMeasure           { get; set; }
    public string   LotNumber               { get; set; }
    public string   SublotNumber            { get; set; }
    public int      LabelSerialNumber       { get; set; }
    public string   PurchaseOrderNumber     { get; set; }
    public string   PurchaseOrderLineNumber { get; set; }
    public DateTime ManufacturingDate       { get; set; }
    public string   LastModifiedUser        { get; set; }
    public DateTime LastModifiedTime        { get; set; }
    public Binary   VersionNumber           { get; set; }

    public ICollection<LotEquipmentScan> LotEquipmentScans { get; private set; }
}

... E lo trasforma in questo:

/// <summary>
/// Container for properties of a raw material label
/// </summary>
public class RawMaterialLabel : EntityBase
{
    /// <summary>
    /// Gets or sets the id.
    /// </summary>
    /// <value>
    /// The id.
    /// </value>
    public long Id { get; set; }

    /// <summary>
    /// Gets or sets the manufacturer id.
    /// </summary>
    /// <value>
    /// The manufacturer id.
    /// </value>
    public string ManufacturerId { get; set; }

    /// <summary>
    /// Gets or sets the part number.
    /// </summary>
    /// <value>
    /// The part number.
    /// </value>
    public string PartNumber { get; set; }

    /// <summary>
    /// Gets or sets the quantity.
    /// </summary>
    /// <value>
    /// The quantity.
    /// </value>
    public string Quantity { get; set; }

    /// <summary>
    /// Gets or sets the unit of measure.
    /// </summary>
    /// <value>
    /// The unit of measure.
    /// </value>
    public string UnitOfMeasure { get; set; }

    /// <summary>
    /// Gets or sets the lot number.
    /// </summary>
    /// <value>
    /// The lot number.
    /// </value>
    public string LotNumber { get; set; }

    /// <summary>
    /// Gets or sets the sublot number.
    /// </summary>
    /// <value>
    /// The sublot number.
    /// </value>
    public string SublotNumber { get; set; }

    /// <summary>
    /// Gets or sets the label serial number.
    /// </summary>
    /// <value>
    /// The label serial number.
    /// </value>
    public int LabelSerialNumber { get; set; }

    /// <summary>
    /// Gets or sets the purchase order number.
    /// </summary>
    /// <value>
    /// The purchase order number.
    /// </value>
    public string PurchaseOrderNumber { get; set; }

    /// <summary>
    /// Gets or sets the purchase order line number.
    /// </summary>
    /// <value>
    /// The purchase order line number.
    /// </value>
    public string PurchaseOrderLineNumber { get; set; }

    /// <summary>
    /// Gets or sets the manufacturing date.
    /// </summary>
    /// <value>
    /// The manufacturing date.
    /// </value>
    public DateTime ManufacturingDate { get; set; }

    /// <summary>
    /// Gets or sets the last modified user.
    /// </summary>
    /// <value>
    /// The last modified user.
    /// </value>
    public string LastModifiedUser { get; set; }

    /// <summary>
    /// Gets or sets the last modified time.
    /// </summary>
    /// <value>
    /// The last modified time.
    /// </value>
    public DateTime LastModifiedTime { get; set; }

    /// <summary>
    /// Gets or sets the version number.
    /// </summary>
    /// <value>
    /// The version number.
    /// </value>
    public Binary VersionNumber { get; set; }

    /// <summary>
    /// Gets the lot equipment scans.
    /// </summary>
    /// <value>
    /// The lot equipment scans.
    /// </value>
    public ICollection<LotEquipmentScan> LotEquipmentScans { get; private set; }
}

2
Direi che XML è una scelta terribile per questo scopo. È troppo prolisso e generale per l'uso a portata di mano. Dai un'occhiata a reStructuredText e sfinge per un linguaggio di markup che si integra nei commenti senza renderli illeggibili.
Latty,

2
@Lattyware: VisualStudio supporta questo stile per impostazione predefinita, non sono necessari plug-in o strumenti aggiuntivi. I commenti generati in questo modo sono immediatamente visibili nelle descrizioni dei comandi a comparsa.
FrustratedWithFormsDesigner,

@FrustratedWithFormsDesigner Direi che vale la pena procurarsi un plugin per rendere il codice molto più leggibile. Supporto integrato per reST con tooltip come quello in PyCharm, quindi sono sicuro che esistono plugin per altre lingue in altri IDE. Ovviamente se hai un progetto in cui tutto è documentato in questo modo, non sto suggerendo di iniziare a dividere il modo in cui è stato fatto, ma per i nuovi progetti, penso solo che sia così orribile da leggere e mantenere.
Latty,

Risposte:


21

Se i tuoi commenti sono solo così:

/// <summary>
/// Gets or sets the sublot number.
/// </summary>
/// <value>
/// The sublot number.
/// </value>

Quindi sì, non sono poi così utili. Se leggono qualcosa del genere:

/// <summary>
/// Gets or sets the sublot number.
/// Note that the sublot number is only used by the legacy inventory system.
/// Latest version of the online inventory system does not use this, so you can leave it null. 
/// Some vendors require it but if you don't set it they'll send a request for it specifically.
/// </summary>
/// <value>
/// The sublot number.
/// </value>

Quindi direi che hanno valore. Quindi, per rispondere alla tua domanda: i commenti sono necessari quando dicono qualcosa che il codice non dice.

Un'eccezione: è bene avere commenti su tutto ciò che è pubblicamente accessibile se si sta scrivendo una libreria / API che sarà disponibile al pubblico. Io odio utilizzando una libreria e di vedere una funzione denominata getAPCDGFSocket()senza alcuna spiegazione di ciò che un APCDGFSocket è (Sarei felice con qualcosa di semplice come This gets the Async Process Coordinator Data Generator File Socket). Quindi, in tal caso, direi di utilizzare uno strumento per generare tutti i commenti e quindi modificare manualmente quelli che ne hanno bisogno (e assicurati che siano spiegati i tuoi acronimi criptici).

Inoltre, i getter / setter sono generalmente cattivi esempi per "sono necessari commenti?" perché di solito sono abbastanza ovvi e non sono necessari commenti. I commenti sono più importanti sulle funzioni che eseguono alcuni algoritmi in cui alcune spiegazioni del perché le cose vengono fatte così come sono potrebbero rendere il codice molto più comprensibile e anche facilitare il lavoro dei futuri programmatori.

... e infine, sono abbastanza sicuro che questa domanda sia pertinente per tutti gli stili di commenti, non solo quelli formattati usando XML (che stai usando perché lavori in un ambiente .NET).


2
+1 - GhostDoc è un punto di partenza per me per trasformare la prima versione, che è boilerplate, nella seconda versione, che contiene una conoscenza dettagliata del dominio.
Jesse C. Slicer,

4
+1 per la parte del perché . Si applica il principio DRY - non ripeterti, e se il codice fa già un buon lavoro nel descrivere quale parte, i tuoi commenti dovrebbero concentrarsi sulla spiegazione di qualcos'altro (in genere il perché ).
Daniel B,

@DanielB o forse non hai affatto bisogno di commenti;) Sono d'accordo per lo più con questa risposta, tranne la parola necessaria in "I commenti sono necessari quando dicono qualcosa che il codice non dice". Penso che se il codice dice tutto il necessario, allora non hai bisogno di più informazioni nei commenti anche se i commenti forniscono informazioni non nel codice.
Jimmy Hoffa,

1
@DanielB - I commenti XML in .NET sono principalmente destinati a situazioni in cui il programmatore dell'utente finale di una libreria o di un servizio non dispone del codice sorgente disponibile.
jfrankcarr,

2
@Lattyware: i commenti XML si integrano perfettamente con Intellisense di Visual Studio, un notevole risparmio di tempo rispetto alla ricerca di contenuti in un documento separato.
jfrankcarr,

5

I commenti che sembrano inutili per gli utenti che possono leggere il codice diventano piuttosto utili per gli utenti che non hanno accesso alla fonte. Ciò accade quando la classe viene utilizzata come API esterna da persone esterne all'organizzazione: gli HTML generati dai tuoi documenti XML sono il loro unico modo per conoscere le tue classi.

Detto questo, un commento che ribadisce il nome del metodo con spazi aggiunti tra le parole rimane inutile. Se la tua classe verrà utilizzata al di fuori della tua organizzazione, devi documentare almeno gli intervalli validi per i tuoi valori. Ad esempio, dovresti dire che l'impostazione UnitOfMeasuresu nullè illegale, che il valore fornito al setter non deve contenere spazi all'inizio o alla fine della stringa e così via. Dovresti anche documentare l'intervallo di LabelSerialNumberse differisce da quello di una pianura Int32: forse non consente numeri negativi *o non consente più di sette cifre. I tuoi utenti interni possono darlo per scontato, perché guardano ogni giorno numeri seriali, ma gli utenti esterni possono essere sinceramente sorpresi nel vedere un'eccezione da quello che sembra un setter innocente.


* ... nel qual caso uintpotrebbe essere una scelta migliore


1
Non è solo per quando non hai la fonte. Se il tuo editor può analizzarli (come fa Visual Studio con i commenti Xml), può fornire informazioni come passaggio del mouse / popup senza richiedere la navigazione in un altro file. Un validatore di intervallo di 1 riga che limita un int a un intervallo più stretto è ovvio quando si passa al file in cui è implementato il setter; ma quando "FrobableID deve essere compreso tra 0 e 1000" appare quando inizi a digitare "myFrobable.Fro ..." e il completamento automatico invia in noi un utile promemoria.
Dan Fiddling By Firelight,

1

Hai assolutamente ragione a evitare commenti così inutili. Rendono più difficile la lettura del codice anziché renderlo più semplice e occupano troppo spazio.

Nella mia pratica le persone che scrivono commenti con getter / setter, tendono a omettere i commenti quando sono realmente necessari (come la creazione di una query sql di 20 righe per un componente senza documentazione).

Scrivo commenti quando ci sono altre soluzioni ovvie _ Indico perché è stato utilizzato esattamente questo approccio. O quando è difficile ottenere l'idea senza conoscere tutti i dettagli, elencherò brevemente i dettagli necessari per comprendere il codice.

L'esempio che porti è più di scrivere commenti per dire che uno scrive commenti piuttosto che rendere più facile la vita degli altri (e anche la loro).

A proposito, puoi migliorare la tua capacità di scrivere commenti tornando al tuo vecchio codice e cercando di comprenderlo (potresti persino non riconoscere il tuo codice in 2-3 mesi _ è assolutamente come leggere il codice di qualcun altro). Se lo fai indolore, allora va tutto bene.


Non conosco più nessuno che si sforzi di scrivere commenti su getter / setter. Se stai usando quasi tutti i moderni IDE (e anche editor di testo avanzati possono supportarlo tramite plug-in), i getter e i setter possono di solito essere documentati molto facilmente con un clic del mouse o due, oppure con il tasto destro (se è stato configurato). A volte vengono generati automaticamente quando si genera codice basato su uno schema di database o WSDL ...
FrustratedWithFormsDesigner

@FrustratedWithFormsDesigner, la persona di cui stavo parlando era di lasciare la società, e credo che tutti quei commenti su getter / setter siano stati fatti da quella persona per dimostrare che ha fatto qualche sforzo per lasciare un po 'di documentazione
superM

Sono stati inseriti tutti i commenti di Bogo dopo che la persona lo ha notificato? Ho visto persone creare commenti xml vuoti / inutili in tutto il luogo come un modo ossessivo per impedire a VS di generare avvisi "Manca commenti xml su Foo pubblicamente visibili".
Dan Is Fiddling By Firelight,

@Nan Neely, immagino che a quella persona non importasse davvero e che abbia appena aggiunto commenti per dire che i commenti vengono aggiunti. Di solito non prestiamo molta attenzione ai commenti, ma se qualcuno deve andarsene e sta lavorando su un componente, è necessario scrivere un codice chiaro e leggibile.
superM
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.