Являются ли комментарии XML необходимой документацией?

10

Раньше я был поклонником требования XML-комментариев для документации. С тех пор я передумал по двум основным причинам:

  1. Как и хороший код, методы должны быть понятны.
  2. На практике большинство XML-комментариев представляют собой бесполезный шум, который не дает никакой дополнительной ценности.

Много раз мы просто используем GhostDoc для генерации общих комментариев, и это то, что я имею в виду под бесполезным шумом:

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

Для меня это очевидно. Сказав это, если есть специальные инструкции для включения, то мы должны обязательно использовать XML-комментарии.

Мне нравится этот отрывок из этой статьи :

Иногда вам нужно будет написать комментарии. Но это должно быть исключением, а не правилом. Комментарии следует использовать только тогда, когда они выражают то, что не может быть выражено в коде. Если вы хотите написать элегантный код, постарайтесь исключить комментарии и вместо этого пишите самодокументированный код.

Я ошибаюсь, полагая, что мы должны использовать комментарии XML только тогда, когда кода недостаточно для самостоятельного объяснения?

Я считаю, что это хороший пример, когда комментарии XML делают красивый код уродливым. Требуется такой класс ...

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

... и превращает это в это:

/// <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
Я бы сказал, что XML - ужасный выбор для этой цели. Это слишком многословный и общий для использования под рукой. Проверьте reStructuredText и sphinx для языка разметки, который встраивается в комментарии, не делая их нечитаемыми.
Latty
2
@Lattyware: VisualStudio поддерживает этот стиль по умолчанию, дополнительные плагины или инструменты не требуются. Сгенерированные таким образом комментарии сразу видны во всплывающих подсказках.
FrustratedWithFormsDesigner
@FrustratedWithFormsDesigner Я бы сказал, что приобретение плагина стоит того, чтобы сделать ваш код более читабельным. Встроенная поддержка reST с всплывающими подсказками в PyCharm, так что я уверен, что плагины существуют для других языков в других IDE. Очевидно, что если у вас есть проект, где все задокументировано таким образом, я не предлагаю вам начинать разделять способ, которым это делается, но для новых проектов я просто думаю, что это так ужасно читать и поддерживать.
Латти

Ответы:

21

Если ваши комментарии выглядят так:

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

Тогда да, они не так уж и полезны. Если они читают что-то вроде этого:

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

Тогда я бы сказал, что они имеют ценность. Итак, чтобы ответить на ваш вопрос: комментарии необходимы, когда они говорят что-то, чего не говорит код.

Исключение: хорошо иметь комментарии ко всему, что является общедоступным, если вы пишете библиотеку / API, которые будут доступны для общественности. Я ненавижу использовать библиотеку и видеть функцию, названную getAPCDGFSocket()без объяснения того, что такое APCDGFSocket (я был бы счастлив с чем-то простым This gets the Async Process Coordinator Data Generator File Socket). Так что в этом случае я бы сказал, использовать какой-то инструмент, чтобы сгенерировать все комментарии, а затем вручную настроить те, которые в нем нуждаются (и, пожалуйста, убедитесь, что объяснены ваши загадочные сокращения).

Кроме того, геттеры / сеттеры, как правило, являются плохими примерами "нужны ли комментарии?" потому что они обычно довольно очевидны и комментарии не нужны. Комментарии более важны для функций, которые выполняют некоторый алгоритм, где некоторое объяснение того, почему все делается именно так, может сделать код намного более понятным, а также облегчить работу будущим программистам.

... и, наконец, я уверен, что этот вопрос актуален для всех стилей комментариев, а не только для тех, которые отформатированы с использованием XML (который вы используете, потому что работаете в среде .NET).

FrustratedWithFormsDesigner
источник
2
+1 - GhostDoc - это отправная точка для меня, чтобы превратить первую версию, которая является образцом, во вторую версию, которая содержит подробные знания предметной области.
Джесси С. Слайсер
4
+1 за часть почему . Применяется принцип СУХОГО - не повторяйте себя, и если код уже довольно хорошо описывает, какую часть, ваши комментарии должны быть сосредоточены на объяснении чего-то другого (как правило, почему ).
Даниэль Б
@DanielB или, может быть, вам вообще не нужны комментарии;) Я согласен по большей части с этим ответом, за исключением слова, необходимого в «Комментарии необходимы, когда они говорят то, что код не говорит». Я думаю, что если код говорит все необходимое, вам не нужно больше информации в комментариях, даже если комментарии дают информацию не в коде.
Джимми Хоффа
1
@DanielB - XML-комментарии в .NET в первую очередь предназначены для ситуаций, когда конечный пользователь-программист библиотеки или службы не имеет доступного им исходного кода.
jfrankcarr
2
@Lattyware - XML-комментарии легко интегрируются с Intellisense в Visual Studio, что значительно экономит время по сравнению с поиском в отдельном документе.
jfrankcarr
5

Комментарии, которые выглядят бесполезными для пользователей, которые могут читать код, становятся довольно полезными для пользователей, которые не имеют доступа к источнику. Это происходит, когда класс используется в качестве внешнего API людьми вне вашей организации: HTML-коды, сгенерированные из ваших документов XML, являются их единственным способом узнать о ваших классах.

Тем не менее, комментарий, который повторяет имя метода с добавленными пробелами между словами, остается бесполезным. Если ваш класс будет использоваться за пределами вашей организации, вам нужно документировать, как минимум допустимые диапазоны для ваших значений. Например, вы должны сказать, что установка UnitOfMeasureна nullнедопустима, что значение, передаваемое в установщик, не должно содержать пробелов в начале или в конце строки и т. Д. Вам также следует задокументировать диапазон значений, LabelSerialNumberесли он отличается от обычного Int32: возможно, он не допускает отрицательных чисел *или не допускает более семи цифр. Ваши внутренние пользователи могут воспринимать это как должное, потому что изо дня в день они смотрят на серийные номера, но внешние пользователи могут быть искренне удивлены, увидев исключение из того, что выглядит невинным сеттером.


* ... в этом случае uintможет быть лучшим выбором

dasblinkenlight
источник
1
Это не только когда у вас нет источника. Если ваш редактор может их анализировать (как это делает Visual Studio с комментариями Xml), они могут предоставлять информацию в виде наведения мыши / всплывающих окон, не требуя перехода к другому файлу. Валидатор диапазона в 1 строку, который ограничивает int более узким диапазоном, очевиден, когда вы переходите к файлу, в котором реализован установщик; но наличие «FrobableID должно быть от 0 до 1000» появляется, когда вы начинаете вводить «myFrobable.Fro ...», и автозаполнение дает нам полезное напоминание.
Дэн играет с огнем
1

Вы абсолютно правы, избегая таких бесполезных комментариев. Они затрудняют чтение кода, а не упрощают его, и занимают слишком много места.

В моей практике люди, которые пишут комментарии с помощью методов получения / установки, обычно пропускают комментарии, когда они действительно необходимы (например, создание 20-строчного SQL-запроса для компонента без документации).

Я пишу комментарии, когда есть другие очевидные решения - я указываю, почему именно этот подход был использован. Или когда трудно понять идею, не зная всех деталей, я кратко перечисляю детали, необходимые для понимания кода.

В качестве примера вы приводите больше написания комментариев, чтобы сказать, что вы пишете комментарии, а не облегчаете жизнь других (и их тоже).

Кстати, вы можете улучшить свои возможности написания комментариев, возвращаясь к своему старому коду и пытаясь понять его (вы можете даже не распознать свой собственный код в течение 2-3 месяцев - это абсолютно похоже на чтение чужого кода). Если вы делаете это безболезненно, тогда все в порядке.

superM
источник
Я не знаю никого, кто больше старается писать комментарии для получателей / установщиков. Если вы используете практически любую современную среду IDE (и даже расширенные текстовые редакторы могут поддерживать это с помощью плагинов), методы получения и установки обычно могут быть очень легко задокументированы одним или двумя щелчками мыши или нажатием правой клавиши (если она настроена). Иногда они генерируются автоматически, когда вы генерируете код на основе схемы базы данных или WSDL ...
FrustratedWithFormsDesigner
@FrustratedWithFormsDesigner, человек, о котором я говорил, должен был покинуть компанию, и я полагаю, что все эти комментарии к получателям / установщикам были сделаны этим человеком, чтобы показать, что он / она приложил некоторые усилия, чтобы оставить некоторую документацию
superM
Были ли введены все комментарии бого после того, как человек дал уведомление? Я видел, как люди создают пустые / бесполезные xml-комментарии повсеместно, как безумный способ не дать VS генерировать предупреждения «Отсутствует xml-комментарий для публично видимых предупреждений Foo».
Дэн возится с огнем
@ Дэн Нили, я думаю, что этому человеку было все равно, и он просто добавил комментарии, чтобы сказать, что комментарии добавлены. Обычно мы не обращаем большого внимания на комментарии, но если кто-то хочет уйти и работает над компонентом, необходимо написать понятный для чтения код.
СуперМ