¿Son los comentarios XML la documentación necesaria?

10

Solía ​​ser un fanático de requerir comentarios XML para la documentación. Desde entonces he cambiado de opinión por dos razones principales:

  1. Como un buen código, los métodos deben explicarse por sí mismos.
  2. En la práctica, la mayoría de los comentarios XML son ruidos inútiles que no proporcionan ningún valor adicional.

Muchas veces simplemente usamos GhostDoc para generar comentarios genéricos, y esto es lo que quiero decir con ruido inútil:

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

Para mí, eso es obvio. Dicho esto, si hubiera instrucciones especiales para incluir, entonces deberíamos usar absolutamente los comentarios XML.

Me gusta este extracto de este artículo :

A veces, tendrá que escribir comentarios. Pero, debería ser la excepción, no la regla. Los comentarios solo deben usarse cuando expresan algo que no puede expresarse en código. Si desea escribir código elegante, trate de eliminar los comentarios y, en su lugar, escriba código autodocumentado.

¿Me equivoco al pensar que solo deberíamos usar comentarios XML cuando el código no es suficiente para explicarse por sí solo?

Creo que este es un buen ejemplo donde los comentarios XML hacen que el código bonito se vea feo. Se necesita una clase como esta ...

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; }
}

... Y lo convierte en esto:

/// <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; }
}
Bob Horn
fuente
2
Yo diría que XML es una elección terrible para este propósito. Es demasiado detallado y general para el uso en cuestión. Consulte reStructuredText y sphinx para ver un lenguaje de marcado que se inserta en los comentarios sin hacerlos ilegibles.
Latty
2
@Lattyware: VisualStudio admite este estilo de forma predeterminada, no se necesitan complementos ni herramientas adicionales. Los comentarios generados de esta manera son visibles de inmediato en la información emergente emergente.
FrustratedWithFormsDesigner
@FrustratedWithFormsDesigner Diría que vale la pena obtener un complemento para que su código sea mucho más legible. El soporte incorporado para reST con información sobre herramientas como esta está en PyCharm, por lo que estoy seguro de que existen complementos para otros idiomas en otros IDE. Obviamente, si tiene un proyecto donde todo está documentado de esta manera, no estoy sugiriendo que comience a dividir la forma en que se hace, pero para proyectos nuevos, creo que es horrible leerlo y mantenerlo.
Latty

Respuestas:

21

Si sus comentarios solo se ven así:

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

Entonces sí, no son tan útiles. Si leen algo como esto:

/// <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>

Entonces diría que tienen valor. Para responder a su pregunta: los comentarios son necesarios cuando dicen algo que el código no dice.

Una excepción: es bueno tener comentarios sobre cualquier cosa que sea de acceso público si está escribiendo una biblioteca / API que estará disponible para el público. Yo odio el uso de una biblioteca y ver una función llamada getAPCDGFSocket()sin ninguna explicación de lo que un APCDGFSocket es (sería feliz con algo tan simple como This gets the Async Process Coordinator Data Generator File Socket). Entonces, en ese caso, diría que use alguna herramienta para generar todos los comentarios y luego modifique manualmente los que lo necesiten (y asegúrese de explicar sus siglas crípticas).

Además, getters / setters son generalmente malos ejemplos de "¿son necesarios los comentarios?" porque generalmente son bastante obvios y los comentarios no son necesarios. Los comentarios son más importantes sobre las funciones que realizan algún algoritmo en el que una explicación de por qué se hacen las cosas de la manera en que están podrían hacer que el código sea mucho más comprensible y también facilitar el trabajo de los futuros programadores.

... y finalmente, estoy bastante seguro de que esta pregunta es relevante para todos los estilos de comentarios, no solo para aquellos que están formateados con XML (que está utilizando porque está trabajando en un entorno .NET).

FrustratedWithFormsDesigner
fuente
2
+1: GhostDoc es un punto de partida para convertir la primera versión, que es repetitiva, en la segunda versión, que contiene un conocimiento detallado del dominio.
Jesse C. Slicer
44
+1 para la parte del por qué . Se aplica el principio DRY: no se repita, y si el código ya hace un buen trabajo al describir qué parte, sus comentarios deberían centrarse en explicar algo más (generalmente el por qué ).
Daniel B
@DanielB o tal vez no necesita comentarios en absoluto;) Estoy de acuerdo en su mayor parte con esta respuesta, excepto la palabra necesaria en "Los comentarios son necesarios cuando dicen algo que el código no dice". Creo que si el código dice todo lo necesario, entonces no necesita más información en los comentarios, incluso si los comentarios dan información que no está en el código.
Jimmy Hoffa
1
@DanielB: los comentarios XML en .NET están destinados principalmente a situaciones en las que el programador del usuario final de una biblioteca o servicio no tiene el código fuente disponible.
jfrankcarr
2
@Lattyware: los comentarios XML se integran perfectamente con Intellisense de Visual Studio, un gran ahorro de tiempo en comparación con buscar cosas en un documento separado.
jfrankcarr
5

Los comentarios que parecen inútiles para los usuarios que pueden leer el código se vuelven bastante útiles para los usuarios que no tienen acceso a la fuente. Esto sucede cuando la clase es utilizada como una API externa por personas externas a su organización: los HTML generados a partir de sus documentos XML son su única forma de aprender acerca de sus clases.

Dicho esto, un comentario que reitera el nombre del método con espacios añadidos entre las palabras sigue siendo inútil. Si su clase se va a usar fuera de su organización, debe documentar al menos los rangos válidos para sus valores. Por ejemplo, debería decir que establecer UnitOfMeasureen nulles ilegal, que el valor suministrado al configurador no debe contener espacios al principio o al final de la cadena, y así sucesivamente. También debe documentar el rango de LabelSerialNumbersi difiere del de un plano Int32: tal vez no permita números negativos *, o no permite más de siete dígitos. Sus usuarios internos pueden darlo por sentado, porque miran los números de serie día tras día, pero los usuarios externos pueden estar genuinamente sorprendidos al ver una excepción de lo que parece un setter inocente.


* ... en cuyo caso uintpuede ser una mejor opción

dasblinkenlight
fuente
1
No es solo para cuando no tienes la fuente. Si su editor puede analizarlos (como lo hace Visual Studio con comentarios Xml), pueden proporcionar información como mouseover / popups sin requerir que navegue a un archivo diferente. Un validador de rango de 1 línea que limita un int a un rango más estrecho es obvio cuando va al archivo donde se implementa el configurador; pero cuando aparece "myFrobable.Fro ..." aparece el mensaje "FrobableID debe estar entre 0 y 1000" y el autocompletado nos envía un recordatorio útil.
Dan Is Fiddling By Firelight
1

Tienes toda la razón al evitar comentarios tan inútiles. Hacen que leer el código sea más difícil en lugar de hacerlo más fácil, y están ocupando demasiado espacio.

En mi práctica, las personas que escriben comentarios con getters / setters, tienden a omitir comentarios cuando son realmente necesarios (como construir una consulta sql de 20 líneas para un componente sin documentación).

Escribo comentarios cuando hay otras soluciones obvias. Indico por qué se ha utilizado exactamente este enfoque. O cuando es difícil entender la idea sin conocer todos los detalles _ Enumero brevemente los detalles necesarios para comprender el código.

El ejemplo que presenta es más de escribir comentarios para decir que uno escribe comentarios en lugar de facilitar la vida de los demás (y de ellos también).

Por cierto, puede mejorar su capacidad de escribir comentarios volviendo a su antiguo código e intentando comprenderlo (incluso podría no reconocer su propio código en 2-3 meses _ es absolutamente como leer el código de otra persona). Si haces esto sin dolor, entonces todo está bien.

superM
fuente
Ya no conozco a nadie que se esfuerce por escribir comentarios sobre getters / setters. Si está utilizando casi cualquier IDE moderno (e incluso los editores de texto avanzados pueden admitir esto a través de complementos), los captadores y configuradores generalmente se pueden documentar muy fácilmente con un clic del mouse o dos, o con la tecla correcta (si se ha configurado). A veces se generan automáticamente cuando genera código basado en un esquema de base de datos o WSDL ...
FrustratedWithFormsDesigner
@FrustratedWithFormsDesigner, la persona de la que estaba hablando debía abandonar la empresa, y creo que todos esos comentarios sobre getters / setters fueron hechos por esa persona para demostrar que hizo un esfuerzo por dejar algo de documentación
superM
¿Se ingresaron todos los comentarios de Bogo después de que la persona dio aviso? He visto a personas crear comentarios xml vacíos / inútiles en todo el lugar como una manera descabellada para evitar que VS genere advertencias "Falta el comentario xml en advertencias Foo visibles públicamente".
Dan está tocando el violín el
@Dan Neely, supongo que a esa persona realmente no le importó y simplemente agregó comentarios para decir que se agregan comentarios. Por lo general, no prestamos mucha atención a los comentarios, pero si alguien se va y está trabajando en un componente, es imprescindible escribir un código claro y legible.
SuperM