Стиль и рекомендации комментирования кода


26

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

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

Хорошо, я начну.

  1. Обычно я не использую /* */комментарии, даже когда мне нужно комментировать много строк.

    Преимущества : код визуально выглядит лучше, чем когда вы смешиваете такой синтаксис с однострочными комментариями. Большинство IDE имеют возможность комментировать выделенный текст, и они обычно делают это с однострочным синтаксисом.

    Недостатки : трудно редактировать такой код без IDE.

  2. Поставьте «точку» в конце любого законченного комментария.

    Например:

    //Recognize wallpaper style. Here I wanted to add additional details
    int style = int.Parse(styleValue);
    //Apply style to image.
    Apply(style);
    

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

  3. Выровняйте текст в перечислениях, комментируя параметры и т. Д.

    Например:

    public enum WallpaperStyle
    {
        Fill = 100,     //WallpaperStyle = "10"; TileWallpaper = "0".
        SizeToFit = 60, //WallpaperStyle = "6";  TileWallpaper = "0".
        Stretch = 20,   //WallpaperStyle = "2";  TileWallpaper = "0".
        Tile = 1,       //WallpaperStyle = "0";  TileWallpaper = "1".
        Center = 0      //WallpaperStyle = "0";  TileWallpaper = "0".
    };
    

    Преимущества : просто выглядит лучше и визуально легче найти то, что вам нужно.

    Недостатки : тратить время на выравнивание и сложнее редактировать.

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

    Например, глупый комментарий:

    //Apply style.
    Apply(style);
    

    Преимущества : у вас будет понятный и небольшой код с только полезной информацией в комментариях.


2
Выровняйте комментарии в vim: используйте Align.vim и выполните :3,7 Align //выравнивание комментариев в строках 3-7.
Бенуа

3
«Трудно редактировать без IDE» - ну, вы делаете это часто?

3
Я думаю, что в вопросе следует отметить предпочтение языка / среды. В некоторых из них есть руководящие принципы (в .NET есть довольно стандартные xml комментарии: msdn.microsoft.com/en-us/library/b2s063f7.aspx ).
Стивен Эверс

+1 СнОрфус. Для Java-комментариев, которые будут использоваться для Javadocs, документацию разработчика необходимо поместить в комментарии с двумя звездочками, которые должны быть помещены перед вашим кодом. А Javadoc-комментарии преобразуются в html, поэтому вы можете использовать в своем комментарии список маркеров, таблицу, изображение или URL, и во всех этих случаях конечная точка может вызывать беспокойство.
пользователь неизвестен

Ответы:


16

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

Типы комментариев

Для краткой версии ... Я использую комментарии для:

  • конечные комментарии, объясняющие поля в структурах данных (кроме них, я не использую однострочные комментарии)
  • исключительные или целенаправленные многострочные комментарии над блоками
  • общедоступная документация пользователя и / или разработчика, сгенерированная из источника

Читайте ниже для деталей и (возможно, неясных) причин.

Последние комментарии

В зависимости от языка, используются однострочные комментарии или многострочные комментарии. Почему это зависит? Это просто вопрос стандартизации. Когда я пишу код на C, я отдаю предпочтение старомодному коду ANSI C89 по умолчанию, поэтому я предпочитаю всегда иметь /* comments */.

Поэтому я хотел бы иметь это в C большую часть времени, а иногда (в зависимости от стиля кодовой базы) для языков с C-подобным синтаксисом:

typedef struct STRUCT_NAME {
  int fieldA;                /* aligned trailing comment */
  int fieldBWithLongerName;  /* aligned trailing comment */
} TYPE_NAME;

Emacs хорош и делает это для меня M-;.

Если язык поддерживает однострочные комментарии и не основан на C, я буду более склонен использовать однострочные комментарии. В противном случае, я боюсь, что теперь взял эту привычку. Что не обязательно плохо, так как заставляет меня быть кратким.

Многострочные комментарии

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

/*
 * this is a multi-line comment, which needs to be used
 * for explanations, and preferably be OUTSIDE the a
 * function's or class' and provide information to developers
 * that would not belong to a generated API documentation.
 */

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

/*
** this is another multi-line comment, which needs to be used
** for explanations, and preferably be OUTSIDE the a
** function's or class' and provide information to developers
** that would not belong to a generated API documentation.
*/

Если это действительно необходимо, то я бы прокомментировал встроенное, используя то, что упомянул ранее для трейлинг-комментариев, если имеет смысл использовать его в трейлинг-позиции. На особом обратном случае, например, или к документу switch«s caseзаявления (редко, я не часто использовать переключатель), или когда документ ветви в if ... elseпотоке управления. Если это не один из них, то, как правило, блок комментария вне области действия, описывающий шаги функции / метода / блока, имеет больше смысла для меня.

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

try {
  /* you'd have real code here, not this comment */
} catch (AwaitedException e) {
  /*
   * Nothing to do here. We default to a previously set value.
   */
}

Что уже безобразно для меня, но я бы терпел в некоторых обстоятельствах.

Документация Комментарии

Javadoc & al.

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

Они немного меня раздражают, документируя поля / свойства, так как я предпочитаю завершающие комментарии для этого, и не все рамки генерации документации поддерживают конечные комментарии документации. Например, Doxygen, а JavaDoc - нет, а это значит, что вам нужен верхний комментарий для всех ваших полей. Я могу пережить это, хотя, поскольку строки Java в большинстве случаев относительно длинные, в любом случае, последний комментарий может меня выпугнуть, если расширить линию за пределы моего порога допуска. Если бы Javadoc когда-нибудь подумал об улучшении этого, я был бы намного счастливее.

Закомментированный код

Я использую однострочные только по одной причине, в языках, подобных C (за исключением случаев компиляции для строгого C, где я их на самом деле не использую): чтобы закомментировать материал при кодировании. Большинство IDE будут иметь переключатели для однострочных комментариев (с выравниванием по отступу или по столбцу 0), и это подходит для этого варианта использования для меня. Использование переключателя для многострочных комментариев (или выбор в середине строки для некоторых IDE) затруднит легкое переключение между комментариями / комментариями.

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

Стили комментариев

Я обычно пишу:

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

Заметка о грамотном программировании

Возможно, вы захотите заинтересоваться грамотным программированием , о котором рассказывает Дональд Кнут .

Парадигма грамотного программирования [...] представляет собой отход от написания программ в порядке и порядке, наложенных компьютером, и вместо этого позволяет программистам разрабатывать программы в порядке, требуемом логикой и потоком их мыслей. 2 Грамотные программы написаны как непрерывное изложение логики на обычном человеческом языке, очень похожем на текст эссе [...].

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

В качестве дополнительного примечания и примера: структура JavaScript underscore.js , несмотря на несоответствие моему стилю комментирования, является довольно хорошим примером хорошо кодированной базы документов и правильно сформированного аннотированного источника - хотя, возможно, не лучшим для использования в качестве ссылка на API).


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


+1 для отличия закомментированного кода от комментариев документации. Я ненавижу охотиться на них: P
deltreme

@deltreme: спасибо. Я чувствую твою боль, я тоже охотюсь за кучей таких в моем текущем продукте. SCM существуют по причине ... Мне очень хочется просто использовать полнотекстовый поиск с регулярным выражением в Eclipse или Emacs и просто уничтожать их один за другим ... У меня есть более продуктивные вещи, к сожалению :(
Хайлем


14

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

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

public void Login(string username, string password)
{
    // Get the user entity
    var user = userRepository.GetUser(username);


    // Check that the user exists
    if (user == null)
    {
        throw new UserNotFoundException();
    }

    // Check that the users password matched
    if (user.HashedPassword != GetPasswordHash(password))
    {
        throw new InvalidUsernamePasswordException();
    }

    //Check that the users account has not expired
    if (user.Expired)
    {
        throw new UserExpiredException();
    }

    //Mark user as logged in
    ...
}

Это может быть возвращено к чему-то, что является намного более читаемым и, возможно, повторно используемым:

public void Login(string username, string password)
{
    var user = GetUserForUsername(username);

    CheckUsersPasswordMatched(user, password);

    CheckUserAccountNotExpired(user);

    MarkUserAsLoggedIn(user);
}

private void User GetUserForUsername(string username)
{
    var user = userRepository.GetUser(username);

    if (user == null)
    {
        throw new UserNotFoundException();
    }
    return user;
}

private void CheckUsersPasswordMatched(User user, string password)
{
    if (user.HashedPassword != GetPasswordHash(password))
    {
        throw new InvalidUsernamePasswordException();
    }
}

private void CheckUserAccountNotExpired(User user)
{
    if (user.Expired)
    {
        throw new UserExpiredException();
    }
}

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

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

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


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

2
Это именно то, что я пришел сюда, чтобы сказать. На самом деле, я трачу столько же времени на размышления об именах переменных, именах методов, именах классов и т. Д., Как и на написание кода. Результатом, я полагаю, является очень приемлемый код. Конечно, у меня иногда есть методы, которые называются что-то вроде checkIfUnitInvestigationExistsAndCreateNewRootCauseListIfItDoes () ... да, имена методов SOMETIMES становятся длинными, но я думаю, что поддержка кода является наиболее важным аспектом разработки (помимо скорости выпуска).
jeremy.mooer

5

Сосредоточьтесь меньше на формате и больше на содержании. Например, комментарии в вашем примере не говорят мне ничего нового. Они хуже, чем бесполезные, так как они отвлекают от чтения кода, и такие комментарии, в лучшем случае, являются неопределенной ссылкой на то, что, по мнению первоначального программиста, он делал во время написания. Я могу видеть из примера кода, что вы применяете стиль «apply (Style)», я могу читать исходные тексты. Я не могу читать ваши мысли, - почему вы это делаете, это то, что комментарий должен сказать мне. например, а не

//Apply style.

Apply(style);

должно быть

// Unlike the others, this image needs to be drawn in the user-requested style apply(style);

Большинство из нас работают в командах над существующим кодом, форматируют так, как это делает остальная команда, так, как это уже делается. Согласованность гораздо важнее, чем красивая.


Читайте более внимательно, для чего этот пример. Я уже упоминал, что: «Например, глупый комментарий:».
Кирилл М

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

3

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


2

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


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

2

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

/** 
 * This is an example, how to waste vertical space,
 * and how to use useless asterixes.
 */

На две строки меньше:

/** This is an example, how to spare vertical space,
    and how to avoid useless asterixes. */

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

Вы даже сэкономите несколько байтов, если используете отступ для отступа.

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


В этом случае IDE и редакторы могут использовать свертывание кода, если вы хотите сохранить экранное пространство. Если вы хотите сохранить байты, вам нужно прекратить кодирование на вашем Commodore 64 :) Если серьезно, если вы хотите сохранить байты (например, для кода на стороне клиента), то компилятор или минификатор сделает это за вас, как вы. не будут нуждаться в комментариях в производстве. Размер кода имеет значение, поскольку чем больше у вас кода, тем больше вероятность ошибок ( возможно ). Но общий размер файла не должен быть проблемой в современном процессе. Храните код в SCM и поддерживайте его соответствующим образом.
Хайлем

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

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

Как я уже сказал, может быть личным. Но подумайте об этом: действительно ли вы видите все эти яркие и забавные рекламные объявления во время просмотра веб-страниц? Большинство людей этого не делают. Вы просто учитесь их блокировать, поскольку вы только что зарегистрировали их как общий шаблон, который вы легко можете заблокировать. Работает для меня для комментариев к документу. По поводу складывания, это может быть утомительно. Для Java мой Eclipse по умолчанию настроен так, чтобы складывать много вещей, потому что мне нравится открывать свои файлы Java и иметь возможность просматривать их как заголовочные файлы C (без использования структуры контура). И я использую Mylyn только для отображения битов, над которыми я работаю.
Хайлем

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

2

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

// 05-24-2011 (John Doe): Changed this method to use Foo class instead of Bar

и обычно часто включает в себя старый код, который был закомментирован (опять же, в этом суть системы VCS, поэтому нет необходимости быть в коде после написания нового кода). Также следует избегать повторяющихся комментариев типа «Зачем нам это нужно?» или, что еще хуже, «Это, вероятно, должно быть переименовано» (потому что существуют сложные инструменты для переименования, поэтому за то время, которое понадобилось вам, чтобы написать этот комментарий, вы могли бы переименовать объект). Опять же, я имею дело с обоими этими комментариями на регулярной основе, в соответствии с:

// (John Doe) 05-24-2011 not sure why we are using this object?
FooBar oFooBar = Quux.GetFooBar(iFooBarID, bSomeBool);
oFooBar.DiscombobulateBaz();

// (John Doe). This method is poorly named, it's used for more 
// than just frazzling arvadents
public int FrazzleArvadent(int iArvadentID)

2
  1. Выберите систему документации, такую ​​как Doxygen, и придерживайтесь ее. Продолжайте проверять представленные документы.
  2. Попробуйте представить кого-то новичка в кодовой базе, который входит и читает ваши документы, могут ли они начать с него? Стажеры на самом деле хороши для этого, сядьте на новую с имеющейся у вас базой документов и простой задачей и посмотрите, как далеко они продвинулись, если они споткнулись, много уверенности в том, что все, что вы им сказали, чтобы они снова пошли, идет в документах.
  3. Сделайте комментарии к документации контрольной точкой в ​​ваших процессах проверки.

1

Читатели кода обычно пытаются ответить на три вопроса:

  1. Что делает этот класс или функция? Если на это сложно ответить, значит, это слишком много. Код, который трудно документировать, обычно просто неверен.
  2. Как мне это использовать? Пример может быть достаточно хорошим.
  3. Этот код удивителен. Почему ты это сделал? Скорее всего ответы: обойти ошибку в сторонних компонентах, потому что очевидный метод оказался слишком медленным

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

Если я увижу «двойную длину», я спрошу: «Какая единица измерения?» Не добавляйте комментарий. Измените имя переменной. Если я вижу блок кода и говорю «что это делает?», Не добавляйте комментарий. Извлеките функцию со значимым именем. Если вы не можете извлечь функцию, потому что для этого потребуется 17 аргументов, выполните рефакторинг кода.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.