Каков ваш личный подход / принимать комментарии?

дублировать

Каковы ваши жесткие правила комментирования?

Разработчик, с которым я работаю, хотел кое-что сказать по поводу комментариев, которые были мне интересны (см. Ниже). Каков ваш личный подход / принимать комментарии?

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

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

26 ответов

Решение

Существует трагический недостаток теории "самодокументируемого кода". Да, чтение кода скажет вам точно, что он делает. Тем не менее, код не может сказать вам, что он должен делать.

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

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

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

1) Краткое описание вверху файла.h или.cpp для класса, объясняющее назначение класса. Это помогает специалистам по техническому обслуживанию получить быстрый обзор, не разбирая весь код.

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

Кроме этого, я склонен комментировать все, что может показаться кому-то странным или странным. Например: "Этот массив основан на 1, а не на 0 из-за бла-бла".

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

Мне всегда нравились комментарии Refactoring по комментированию:

Причина, по которой мы упоминаем комментарии здесь, заключается в том, что комментарии часто используются в качестве дезодоранта. Удивительно, как часто вы смотрите на комментированный код и замечаете, что там есть комментарии, потому что код плохой.

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

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

Вам нужна документация (в некоторой форме; не всегда комментарии) для локального понимания кода. Код сам по себе говорит вам, что он делает, если вы прочитали все это и можете помнить все это. (Подробнее об этом ниже.) Комментарии лучше всего подходят для неформальной или полуформальной документации.

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

Документируйте контракт каждой функции и, для каждого типа объекта, то, что он представляет, и любые ограничения на допустимое представление (технически, функцию абстракции и инвариант представления). По возможности используйте исполняемую тестируемую документацию (doctests, модульные тесты, утверждения), а также пишите короткие комментарии, где суть полезна. (Там, где тесты принимают форму примеров, они неполны; там, где они полны, точные контракты, они могут потребовать столько же усилий, сколько и сам код.) Пишите комментарии верхнего уровня для каждого модуля и каждого проекта; они могут объяснить соглашения, которые делают все ваши другие комментарии (и код) короткими. (Это поддерживает именование как документацию: с установленными соглашениями и местом, где мы можем найти отмеченные тонкости, мы можем чаще быть уверены, что имена говорят все, что нам нужно знать.) Более длинные, стилизованные, раздражающе избыточные Javadoc имеют свои использует, но помог генерировать обратную реакцию.

(Например, это:

Выполните n -кратную фробуляцию.
@ param n количество раз, чтобы заморозить
@param x x-координата центра фробуляции
@param y y-координата центра вспышки
@param z z-координата центра вспышки

может быть что-то вроде "Frobulate n раз вокруг центра (x,y,z)". Комментарии не должны быть рутиной, чтобы читать и писать.)

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

Вернемся к утверждению, которое мы документируем ради местного понимания: что делает эта функция?

def is_even(n): return is_odd(n-1)

Проверяет, является ли целое число четным? Если is_odd() проверяет, является ли целое число нечетным, тогда да, это работает. Предположим, у нас было это:

def is_odd(n): return is_even(n-1)

Это же рассуждение говорит об этом is_odd() проверяет, является ли целое число нечетным Разложите их вместе, конечно, и ни один из них не работает, хотя каждый из них работает, если другой работает. Измените его немного, и у нас будет код, который работает, но только для натуральных чисел, и в то же время локально выглядит так, как будто он работает для целых чисел. В микромире это то, на что похоже понимание кодовой базы: отслеживание зависимостей в кругах, чтобы попытаться перепроектировать предположения, которые автор мог бы объяснить в одной или двух строках, если бы они беспокоились. Я ненавижу то, что дух бездумных программистов заставил меня пойти на это за последние пару десятилетий: о, этот метод выглядит так, как будто у него есть побочный эффект, чтобы побороть варпкор... всегда? Ну, если странные кробункулы обесцвечивают, по крайней мере; они? Лучше проверь весь код обработки crobuncle... который создаст свои собственные проблемы для понимания. Хорошая документация сокращает эту O(n) погоню за указателями до O(1): например, зная контракт функции и контракты вещей, которые она явно использует, код функции должен иметь смысл без каких-либо дополнительных знаний о системе. (Здесь контракты говорят is_even() а также is_odd() работа с натуральными числами скажет нам, что обе функции должны проверить n==0.)

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

Цель комментариев - объяснить контекст - причину кода; это, программист не может знать из простой проверки кода. Например:

strangeSingleton.MoveLeft(1.06);
badlyNamedGroup.Ignite();

кто знает, какого черта это для? но с простым комментарием все раскрывается:

//when under attack, sidestep and retaliate with rocket bundles
strangeSingleton.MoveLeft(1.06);
badlyNamedGroup.Ignite();

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

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

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

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

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

Так, например, если вы использовали какую-то арифметику указателей в стиле C в небезопасном кодовом блоке C#, вы не должны ожидать, что программисты C# легко переключатся с чтения кода C# (которое, вероятно, обычно более декларативно или, по крайней мере, меньше, чем ниже). -уровень манипулирования указателем), чтобы иметь возможность понять, что делает ваш небезопасный код.

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

В общем, я вижу комментарии, используемые для объяснения плохо написанного кода. Большая часть кода может быть написана таким образом, чтобы комментарии были излишними. Сказав, что я оставляю комментарии в коде, где семантика не интуитивна, например, вызов API, который имеет странное или неожиданное поведение и т. Д.

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

РЕДАКТИРОВАТЬ: Это звучало немного помпезно, но я думаю, что слишком многие люди забывают, что даже имена переменных или структур, которые мы используем в коде, все просто "теги" - они имеют значение только для нас, потому что наш мозг увидеть строку символов, таких как customerNumber и понимаю, что это номер клиента. И хотя это правда, что в комментариях отсутствует какое-либо "принудительное применение" компилятором, они не так уж и удалены. Они предназначены для передачи смысла другому человеку, человеку-программисту, который читает текст программы.

Если код не понятен без комментариев, сначала сделайте код более четким заявлением о намерениях, затем добавляйте комментарии только по мере необходимости.

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

Требование комментариев и "измерения производительности" в строках кода может привести к нежелательным последствиям, таким как:

/*****
 *
 * Increase the value of variable i,
 * but only up to the value of variable j.
 *
 *****/

if (i < j) {
    ++i;
} else {
    i = j;
}

а не краткий (и понятный программисту с соответствующей квалификацией):

i = Math.min(j, i + 1);

YMMV

Подавляющее большинство моих комнетов находятся на уровне класса и метода, и мне нравится описывать представление более высокого уровня, а не просто args/return value. Я особенно осторожен, чтобы описать любые "нелинейности" в функции (пределы, угловые случаи и т. Д.), Которые могут сбить с толку неосторожных.

Обычно я не комментирую внутри метода, за исключением пометки элементов "FIXME", или очень редко что-то вроде "здесь быть монстрами", которые я просто не могу вычистить, но я очень стараюсь избегать их. Как говорит Фаулер в Refactoring, комментарии, как правило, указывают на незначительный код.

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

В общем, при программировании вы должны делать вещи только в одном месте.

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

Однако, если потребуется дальнейшее объяснение, я добавлю комментарий с префиксом INFO, NOTE и аналогичным...
ИНФОРМАЦИЯ: комментарий для общей информации, если кто-то незнаком с этой областью.
ПРИМЕЧАНИЕ: комментарий предназначен для предупреждения о потенциальной странности, такой как странное бизнес-правило / реализация.
Если я специально не хочу, чтобы люди касались кода, я мог бы добавить ПРЕДУПРЕЖДЕНИЕ: или аналогичный префикс.

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

Как подрядчик, я знаю, что некоторые люди, поддерживающие мой код, будут незнакомы с расширенными функциями ADO.Net, которые я использую. При необходимости я добавляю краткий комментарий о намерениях моего кода и URL-адрес на страницу MSDN, который объясняет более подробно.

Я помню, как изучал C# и читал чужой код, я часто расстраивался из-за таких вопросов, как "какое из 9 значений символа двоеточия означает это?" Если вы не знаете название функции, как вы ее ищите?! (Примечание: это была бы хорошая функция IDE: я выбираю оператор или другой токен в коде, щелчок правой кнопкой мыши затем показывает мне его языковую часть и имя функции. Это нужно C#, VB меньше.)

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

И мне нравится @17 из 26 комментариев (добавлен empahsis):

... чтение кода скажет вам точно, что он делает. Тем не менее, код не может сказать вам, что он должен делать.

Я предпочитаю использовать комментарии типа "Гензель и Гретель"; небольшие заметки в коде о том, почему я делаю это таким образом, или почему какой-то другой способ не подходит. Следующему человеку, посетившему этот код, вероятно, понадобится эта информация, и чаще всего этим человеком будет я.

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

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

Я очень очень редко комментирую. Моя теория, если вы должны комментировать, это потому, что вы не делаете вещи наилучшим образом. Как "обходной путь" это единственное, что я хотел бы прокомментировать. Потому что они часто не имеют смысла, но есть причина, по которой вы делаете это, поэтому вам нужно объяснить.

Комментарии являются симптомом подпункта кода IMO. Я твердо верю в самодокументированный код. Большая часть моей работы может быть легко переведена, даже неспециалистом, из-за описательных имен переменных, простой формы, точных и многих методов (IOW не имея методов, которые делают 5 разных вещей).

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

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

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

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

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

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

Я также пытаюсь дать методы и классы заголовков документации, что хорошо для intellisense и автоматически сгенерированной документации. У меня действительно плохая привычка оставлять 90% моих методов и классов без документов. У вас нет времени документировать вещи, когда вы занимаетесь программированием, и все постоянно меняется. Затем, когда вы закончите, вам не хочется возвращаться и находить все новые вещи и документировать их. Вероятно, хорошо возвращаться каждый месяц или около того и просто написать кучу документации.

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

Таким образом, в этом случае комментирование кажется излишним:

/*
 * this function adds two integers
 */
int add(int x, int y)
{
    // add x to y and return it
    return x + y;
}

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

Вот мой взгляд (на основе нескольких лет докторских исследований):

Существует огромная разница между комментированием функций (вроде использования черного ящика, например JavaDocs) и комментированием реального кода для того, кто будет читать код ("внутреннее комментирование").

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

Теперь функциональные комментарии действительно являются проблемой, и в некотором смысле ваш друг прав, что для большей части кода нет экономического стимула для полных спецификаций, как документирование популярных API. Здесь важно определить, что такое "директивы": директивы - это те информационные фрагменты, которые напрямую влияют на клиентов и требуют некоторых прямых действий (и часто являются неожиданными). Например, X должен быть вызван до Y, не вызывайте его извне потока пользовательского интерфейса, помните, что это имеет определенный побочный эффект и т. Д. Это то, что действительно важно захватить.

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

При программировании на C я буду использовать многострочные комментарии в заголовочных файлах для описания API, например параметров и возвращаемого значения функций, макросов конфигурации и т. Д.

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

Если вам когда-либо понадобится несколько строк комментариев для объяснения того, что делает данный фрагмент кода, вам следует серьезно подумать, если то, что вы делаете, не может быть сделано лучше...

Вот как я написал код:

if (hotel.isFull()) {
    print("We're fully booked");
} else {
    Guest guest = promptGuest();
    hotel.checkIn(guest);
}

Вот несколько комментариев, которые я мог бы написать для этого кода:

// if hotel is full, refuse checkin, otherwise 
// prompt the user for the guest info, and check in the guest.

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

С другой стороны, бывают ситуации, когда невозможно или крайне сложно сделать код похожим на прозу; вот где комментарий может быть исправлен.

Мы добавляем комментарии, которые предоставляют справочную документацию по API для всех общедоступных классов / методов / свойств / и т. Д.... Это того стоит, потому что документация XML в C# имеет приятный эффект от предоставления IntelliSense пользователям этих общедоступных API. Контракты на.NET 4.0 позволят нам улучшить эту практику.

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

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

Я комментирую столько, сколько нужно - тогда, сколько мне понадобится год спустя.

Мой подход:

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

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

Использование хорошо отформатированных XML -комментариев самоочевидно.

Небрежное комментирование означает небрежный код!

Другие вопросы по тегам