Как бороться с тавтологией в комментариях? [закрыто]

54

Иногда я нахожусь в ситуациях, когда часть кода, которую я пишу, является (или кажется ) настолько очевидной, что ее имя будет в основном повторяться в виде комментария:

class Example
{
    /// <summary>
    /// The location of the update.
    /// </summary>
    public Uri UpdateLocation { get; set; };
}

(Пример C #, но, пожалуйста, обращайтесь к этому вопросу как к не зависящему от языка).

Такой комментарий бесполезен; Что я делаю неправильно? Это неправильный выбор имени? Как я мог бы прокомментировать такие части лучше? Должен ли я просто пропустить комментарий к таким вещам?

Тамас Селеи
источник
8
Примечание: я бы посчитал «местоположение обновления» очень расплывчатым, если не совсем ясно, что такое «обновление». Поддерживает ли система другие типы URI, кроме URL?
34
return result # returns result
Лукас Стейскал
27
Путь к тавтологии в комментариях - это способ к тавтологии в комментариях. (Это комментарий.)
Rex Kerr
29
Это на самом деле не комментарий, а документация, написанная в форме комментария. К документации API применяются другие правила, чем для встроенных комментариев кода.
Коди Грей,
10
Это просто пример плохой документации API, а не комментарии кода. Мой формат C # XML для такого свойства будет выглядеть примерно так: «Получает или задает Uri, который можно использовать для доступа к серверу обновлений этого объекта».
Кевин Маккормик,

Ответы:

13

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

Это не значит, что нет времени для комментариев; напротив, есть много времени для тавтологических комментариев, которые отбрасывают перефразированную версию того, что комментируется. Они прекрасно работают в качестве отправной точки .

Особенно с учетом того, что Visual Studio использует комментарии, сопровождающие IntelliSense , рекомендуется начать с небольшой информации о поле:

class Example
{
    /// <summary>
    /// The location of the update.
    /// </summary>
    public Uri UpdateLocation { get; set; };
}

И затем, когда вы продолжаете кодировать, когда вы не можете вспомнить, UpdateLocationбыло ли место, где произошло обновление, или местоположение, в которое отправляется обновление, вам придется вернуться к коду. Именно в этот момент вы должны добавить эту дополнительную информацию:

class Example
{
    /// <summary>
    /// The Uri location where the update took place.
    /// </summary>
    public Uri UpdateLocation { get; set; };
}

Если когда-нибудь другой программист спросит вас о деталях поля, обновите комментарии этой информацией:

Какие обновления следует Example.UpdateLocationиспользовать для хранения?

class Example
{
    /// <summary>
    /// The Uri location where the Foo update took place.
    /// </summary>
    public Uri UpdateLocation { get; set; };
}

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

И так же, как программирование, ваши комментарии должны где-то начинаться. Тавтологические комментарии - это Hello World!комментарии, по мере того, как вы будете практиковаться в написании и обновлении документации, ваша начальная документация будет становиться все более устойчивой.

zzzzBov
источник
+1 за то, что был единственным человеком, который фактически дал альтернативный комментарий; а не просто тавтологические ответы.
Ян Бойд
На самом деле это лучший ответ на данный момент.
Роланд Тепп
1
В моем текущем проекте меня поразило больше, чем я могу сосчитать из-за отсутствия комментариев к большой базе устаревшего кода. Что-то Вы, как автор, думаете, что это явно очевидное название метода для чего-то, что вы считаете довольно очевидной функциональностью, а не может быть таким же самодокументированным через три месяца для другого разработчика. В документации по методам, свойствам и полям следует попытаться представить контекст для более широкой картины, и этот ответ объясняет лучший процесс достижения этой цели, который я видел до сих пор.
Роланд Тепп
1
@RolandTepp, я полностью понимаю, откуда ты. И я полностью согласен. Проблема, как я вижу, состоит в том, что многие программисты видят комментарии и документацию как то, что происходит после того, как код завершен и готов к отправке, а не как то, что происходит с кодом как часть процесса разработки, требующего отслеживания ошибок и поддержки вместе с остальной частью кода.
zzzzBov
54

Комментарии никогда не должны дублировать ваш код. Комментарии должны отвечать не на вопросы « как? », А только на « почему? » И « что? ». Почему выбран такой алгоритм, каковы здесь неявные предположения (если ваш язык не достаточно силен, чтобы выразить его с помощью системы типов, контрактов и т. Д.), Что является причиной для того, чтобы делать это вообще и т. Д.

Я бы посоветовал взглянуть на практику грамотного программирования для вдохновения.

SK-логика
источник
+1 - это ответ! Нам не нужны комментарии, такие как «Объявление переменных», «Счетчик приращений» (в цикле) и т. Д.
ozz
так что в примере ОП, что было бы хорошим комментарием?
Стийн
4
@stijn, я не знаю - это (очевидно) отсутствует в коде. То, что только автору кода известно о его назначении и ограничениях.
SK-logic
Возможно, какой-то комментарий, например // Обновляет RaiseShielders в соответствии с levelOfAttack (передается как URL)
woliveirajr
15
Самый важный вопрос, на который должен ответить комментарий: « WTF? »
naught101
53

Комментарии должны описывать код, а не дублировать его. Этот заголовок комментария просто дублирует. Пропусти это.

mjfgates
источник
17
+1: я думаю, я понимаю, что вы имеете в виду, но я не согласен с тем, что вы сказали :-) Насколько это возможно, код должен описывать код, тогда как комментарии должны описывать ваши рассуждения.
Kramii восстановит Монику
3
@Kramii, к сожалению, код неспособен описать код, даже если вы пишете в Agda. Никакие языки не являются такими мощными и выразительными, как естественный язык. И часто вам понадобятся графики, графики, таблицы, сложные формулы для описания кода - едва ли это возможно без надлежащего грамотного программирования.
SK-logic
6
@ SK-логика: я не согласен. Длинный метод менее самоописуем, чем короткий метод, который вызывает ряд хорошо названных подпрограмм.
Kramii Восстановить Монику
3
@Kramii, извини, я не вижу, с чем ты не согласен и как твой комментарий связан с тем, что я сказал. Я хочу сказать, что вместе с вашим кодом должно быть предоставлено много информации, которая полностью отсутствует в самом коде. Вся история решений, которые вы приняли, все соответствующие ссылки на документы и т. Д. - нет языковых элементов для выражения таких вещей. И длинные, и короткие методы / функции / подпрограммы / все, что здесь не имеет никакого значения.
SK-logic
2
@ SK-logic, то, что говорит Крэмий, означает: «Код должен быть легким для чтения и понимания сам по себе», и все графики и т. Д., Которые вы упоминаете, попадают в то, что он говорит как: «комментарии должны описывать ваши рассуждения»
Шахбаз
36

Оставь их!

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

Положите их в!

Ваш пример иллюстрирует два исключения из этого правила:

Во-первых, «UpdateLocation» может (в зависимости от контекста) быть неоднозначным. В этом случае вам нужно либо дать ему лучшее имя, либо оставить комментарий, чтобы убрать эту двусмысленность. Улучшение имени обычно является лучшим вариантом, но это не всегда возможно (например, при реализации опубликованного API).

Во-вторых, «///» в C # указывает комментарий, который предназначен для автоматического создания документации. Среда IDE использует эти комментарии для подсказок, и существуют инструменты (Sandcastle), которые могут генерировать файлы справки и т. Д. Из этих комментариев. Таким образом, есть аргументы для вставки этих комментариев, даже если методы, которые они документируют, уже имеют описательные имена. Однако даже тогда многие опытные разработчики будут недовольны дублированием информации. Решающим фактором должны быть потребности тех, для кого предназначена документация.

Kramii Восстановить Монику
источник
Это лучший ответ. Вы должны быть в состоянии точно выяснить, для чего будет использоваться свойство, когда вы используете класс Example и наводите курсор на свойство.
Энди
В таких ситуациях я стараюсь (и часто не), добавить по крайней мере , либо <remarks/>или <see/>так на то, чтобы обеспечить некоторый дополнительный контент. Это <summary/>все еще дублируется, но в целом комментарий не совсем бесполезен.
EarlNameless
20

Я категорически не согласен с ответами «не пишите комментарии». Почему? Позвольте мне отметить, немного изменив ваш пример.

public Uri UpdateLocation ();

Итак, что делает эта функция:

  • Возвращает ли это «обновление местоположения»? или же
  • Это "обновляет" местоположение и возвращает новое местоположение?

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

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

DPD
источник
4
Я не думаю, что кто-то защищает, не пишите никаких комментариев вообще. Большинство / все говорят «напишите соответствующие комментарии», под которым будет пример UpdateLocation.
Оз
16
Uri UpdateLocation()будет отклонен при проверке кода и будет изменен либо на, Uri GetUpdateLocation()либо на void UpdateLocation().
Авакар
4
@avakar: согласен с мнением, но поскольку это свойство C # (get и set автоматически синтезируются и имеют одно и то же имя), переименование в GetUpdateLocationприведет к получению подобного кода GetUpdateLocation = somelocation. LocationOfUpdateбыло бы лучшим именем, которое устраняет двусмысленность. Основная проблема состоит в том, что OP использовал префикс глагола вместо существительного. Предполагается, что ведущие глаголы указывают на действие метода.
Муравей
2
@DPD, «Сколько времени и усилий требуется, чтобы соединить одну линию», сколько усилий нужно для ее поддержания? Сколько имущества экрана это тратит? Сколько времени это тратит впустую, когда он в конечном счете не синхронизируется с кодом и начинает сбивать с толку разработчиков?
Авакар
1
Метод возвращает значение и имеет имя глагольной фразы. Это проблема. У него должно быть имя-имя. например, «Uri LocationOfUpdate ()». Не GetUpdateLocation, вы говорите «каков ваш GetLocation?»?
Ctrl-Alt-Delor
14

/// <summary>блоки используются для создания документации для документации IntelliSense и API .

Таким образом, если это общедоступный API, вы всегда должны включать хотя бы <summary>комментарий, даже если цель функции должна быть очевидна для читателей.

Однако это исключение из правила; в общем, просто не забудьте СУХОЙ (не повторяйте себя) .

Peter Mortensen
источник
5

Заполняйте комментарии таким образом, только если вы знаете, как вы выиграете от подобных вещей; в противном случае просто протрите их.

Для меня очевидным преимуществом было то, что была автоматическая проверка на отсутствие комментариев, и я использовал эту проверку для обнаружения кода, где необходимо заполнить важную информацию; для этого я действительно заполнил некоторые заполнители - просто чтобы убедиться, что отчет инструмента не содержит «ложных тревог».

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

В этом конкретном примере я бы использовал что-то «самоописательного характера» (при условии, что это не тот случай, когда уничтожение выполнит эту работу), например:

class Example
{
    /// <summary>
    /// Self descriptive method name.
    /// </summary>
    public Uri UpdateLocation { get; set; };
}

Примером, когда я мог бы использовать приведенные выше добрые наполнители, были бы комментарии Javadoc, которые требуют выделенных полей для возвращаемого значения, параметров и исключений. Довольно часто я нахожу, что имеет смысл описать большинство или даже все это в одном кратком предложении, метод, который возвращает <описать, что возвращается> для предоставленных параметров <описать параметры> . В подобных случаях я заполняю формально обязательные поля простым текстом, см. Выше , указывая читателю на краткое описание.

комара
источник
3

Вот вопрос , который я хотел бы спросить себя, думая о том , чтобы добавить комментарий в раздел кода: Что я могу передать , что помогло бы следующему человеку понять общее намерение коды лучше, так что они могут обновить, исправить, или продлить его быстрее и надежнее?

Иногда правильный ответ на этот вопрос заключается в том, что вы ничего не можете добавить к этому моменту в коде, потому что вы уже выбрали имена и соглашения, которые делают намерение настолько очевидным, насколько это возможно. Это означает, что вы написали надежный самодокументированный код, и что вставка комментария туда, скорее всего, отвлечет больше, чем поможет. (Обратите внимание, что избыточные комментарии могут на самом деле со временем повредить надежности кода, замедляя несинхронизацию с реальным кодом с течением времени и, таким образом, затрудняя расшифровку реального намерения.

Тем не менее, почти в любой программе и на любом языке программирования вы столкнетесь с моментом, когда определенные критические концепции и решения, принятые вами самим программистом, больше не будут видны в коде. Это в значительной степени неизбежно, потому что хороший программист всегда программирует на будущее, то есть не только для того, чтобы заставить программу работать один раз, но и для того, чтобы все ее будущие исправления, версии, расширения, модификации и порты были известны и кто знает, что делать. также работает правильно. Этот последний набор целей намного сложнее и требует гораздо большего мышления, чтобы преуспеть. Также очень трудно хорошо выразить себя на большинстве компьютерных языков, которые больше сосредоточены на функциональности, то есть на том, что это означает. Версию программы нужно сделать, прямо сейчас, чтобы она была удовлетворительной.

Вот простой пример того, что я имею в виду. В большинстве языков быстрый встроенный поиск небольшой структуры данных будет достаточно сложным, чтобы кто-то, впервые смотрящий на него, скорее всего, не сразу понял, что это такое. Это возможность для хорошего комментария, потому что вы можете добавить кое-что о намерениях вашего кода, что более поздний читатель, скорее всего, сразу же оценит как полезный для расшифровки деталей.

И наоборот, в таких языках, как язык Prolog, основанный на логике, выражение поиска в небольшом списке может быть настолько невероятно тривиальным и лаконичным, что любой добавленный вами комментарий будет просто шумом. Таким образом, хорошее комментирование обязательно зависит от контекста. Это включает в себя такие факторы, как сильные стороны языка, который вы используете, и общий контекст программы.

Суть заключается в следующем: думать о будущем. Спросите себя, что для вас важно и очевидно о том, как программу следует понимать и изменять в будущем. [1]

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

Но для тех частей вашего кода, где вы приняли критическое решение из нескольких вариантов или если сам код достаточно сложен, чтобы его назначение было неясным, добавьте свои специальные знания в виде комментария. Хороший комментарий в таком случае - это тот, который позволяет будущему программисту знать, что должно быть неизменным - это, кстати, концепция инвариантного утверждения - и что можно изменить.


[1] Это выходит за рамки вопроса комментариев, но стоит упомянуть: если вы обнаружите, что у вас есть очень четкое представление о том, как ваш код может измениться в будущем, вам, вероятно, следует подумать не только о комментариях и встраивании этих параметров. в самом коде, поскольку это почти всегда будет более надежным способом обеспечения надежности будущих версий вашего кода, чем попытка использовать комментарии, чтобы направить неизвестного будущего человека в правильном направлении. В то же время вы также хотите избежать чрезмерной генерализации, поскольку люди, как известно, плохо предсказывают будущее, и это включает в себя будущее программных изменений. Поэтому постарайтесь определить и охватить разумные и проверенные измерения будущего на всех уровнях разработки программ, но не

Терри Боллинджер
источник
3

В моем собственном коде я часто оставляю тавтологии комментариев, в том числе такие вопиющие, как:

<?php
// return the result
return $result;
?>

... которые, очевидно, мало способствуют тому, чтобы сделать код более понятным с точки зрения объяснения.

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

Я думаю о коде как о структуре, которая очень похожа на английский язык, в которой есть «предложения» и «параграфы» (даже если «параграф» может состоять исключительно из одного «предложения»). Я обычно включаю разрыв строки и однострочное резюме над каждым «абзацем». Например:

<?php
//get the id of the thing
$id = $_POST['id'];

//query the things out of the the database
$things = array();
$result = mysql_query("SELECT * FROM Things WHERE `id` = $id");
while ($row = mysql_fetch_assoc($result)) {
    //create a proper Thing object or whatever
    $things[] = new Thing($row);
}

//return the things
return $things;
?>

(Игнорируйте неполный код, SQL-инъекции и т. Д. Вы поняли идею.)

Для меня последний комментарий действительно добавляет ценность к коду, просто потому, что помогает визуально отделить один «абзац» от другого, поддерживая согласованную схему раскраски.

chrisallenlane
источник
Мне трудно заставить подсвечивание синтаксиса работать в моем ответе здесь. Если какой-нибудь редактор может прийти за мной и заставить его работать, я был бы очень признателен, учитывая, что цвета важны для моей аргументации.
Крис Аллен Лэйн
Я добавил синтаксис, подсвечивающий языковые подсказки для вас.
Пагло Эберманн
2

Комментарии должны быть использованы для выполнения одного из следующих действий.

  1. Информация для генераторов документов, чтобы захватить. Это нельзя недооценивать, это чрезвычайно важно.
  2. Предупреждения о том, почему кусок кода такой, какой он есть, и какие другие соображения. Я имел дело с кодом, написанным на 2 языках программирования. Одной из ключевых частей этого было создание общей структуры между двумя языками. Комментарий в обоих местах, информирующий пользователя о том, что если он изменит этот номер, ему также необходимо изменить другой, очень полезен.
  3. Напишите заметки, чтобы объяснить, почему особенно странно выглядящий фрагмент кода таков. Если вам нужно было подумать о том, как заставить фрагмент кода работать определенным образом, а решение с самого начала не очевидно, вероятно, стоит объяснить, что вы пытались сделать.
  4. Маркировка входов / выходов, если они не понятны. Всегда полезно знать, какой будет ваша информация и в каком формате.

Комментарии не должны использоваться для следующих целей:

  1. Объясните вещи, которые чрезвычайно очевидны. Я когда - то видел , унаследованного кода , как это: page=0; // Sets the page to 0. Я думаю, что любой компетентный человек мог понять это.
PearsonArtPhoto
источник
2

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

property UpdateLocation:TUpdateLocation;  // url="http://x/y/3.2/upd.aspx",proto=http

Теперь я точно знаю, что там происходит, и из комментария у меня есть четкое представление о том, как его использовать.

Уоррен П
источник
0

Я бы сказал, что это зависит от цели комментариев.

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

Если комментарии сгенерируют документацию для какой-либо географически удаленной команды, то я бы поместил туда всю информацию.

Энди Хант
источник
0

Я думаю, что эта тема обсуждалась довольно широко под такими названиями, как «комментарии: анти-шаблоны» или «комментарии - это запах кода?» ( один пример ).

Я склонен согласиться с общей идеей, что комментарии должны добавлять новую информацию, а не дублировать. Добавляя подобные тривиальные комментарии, вы нарушаете DRY и уменьшаете отношение сигнала к шуму в коде. Я склонен находить комментарии высокого уровня, объясняющие обязанности, обоснование и пример использования класса, гораздо более полезные, чем комментарии для отдельных свойств (особенно лишние).

Лично в вашем примере я бы оставил комментарий (если на самом деле нет ничего полезного, чтобы добавить об этом свойстве).

Даниэль Б
источник
0

Если вы можете написать код, который не требует комментариев, то вы достигли нирваны программирования !.

Чем меньше комментариев требует ваш код, тем лучше код!

Джеймс Андерсон
источник
3
Это невозможно (и никогда не будет). За кодом всегда остается много вещей - неявные предположения, архитектурные решения, длинные цепочки математических преобразований, заканчивающиеся определенным алгоритмом и т. Д.
SK-logic
1
Возможно "Hello World!" тогда программист нирвана ...
naught101
: -} - Это то, что очень редко достигается - дело в том, что если вы пытаетесь найти комментарий, который добавляет значение, то просто порадуйтесь себе, значит, ваш код верен!
Джеймс Андерсон
0

Такой комментарий бесполезен; Что я делаю неправильно?

Это только кажется бесполезным, если вы уже знаете, что UpdateLocationделает. Является ли «обновление» здесь глаголом или существительным? То есть это то, что обновляет местоположение, или это место обновления? Можно сделать вывод о последнем из того факта, что UpdateLocationэто, по-видимому, свойство, но суть в том, что иногда не мешает явно заявить о чем-то, что кажется очевидным.

Калеб
источник
0

Помимо автоматически скомпилированной документации, код должен документировать сам, так что комментарии должны документировать только там, где кода недостаточно для документирования самого себя.

Ando
источник
-1

«Местоположение» вроде бы очевидно, но «Обновление» может быть немного расплывчатым. Если вы не можете написать лучшее имя, можете ли вы предложить более подробную информацию в комментарии? Обновление чего? Зачем нам это нужно? Каковы некоторые предположения (допустимо ли null)?

Скотт Уитлок
источник