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


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 SnOrfus. Щоб Java-коментарі використовувались для Javadocs, документацію для розробників, потрібно розмістити в коментарях подвійної астерикси, які потрібно розмістити перед вашим кодом. І Javadoc-коментарі перетворюються на html, тому ви можете використовувати список коментарів, таблицю, зображення чи URL-адресу у своєму коментарі, і у всіх випадках випадкові точки можуть бути тривожними.
користувач невідомий

Відповіді:


16

Деякі з наведених нижче тверджень є досить особистими, хоча з певним виправданням, і мають бути таким чином.

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

Для короткої версії ... я використовую коментарі для:

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

Детальніше та (можливо, незрозумілі) причини читайте нижче.

Останні коментарі

Залежно від мови, використовуючи однорядкові або багаторядкові коментарі. Чому це залежить? Це лише питання стандартизації. Коли я пишу код С, я віддаю перевагу старомодному коду ANSI C89 за замовчуванням, тому вважаю за краще завжди мати /* comments */.

Тому я мав би це в C більшій частині часу, а іноді (залежить від стилю бази коду) для мов з C-подібним синтаксисом:

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

Emacs приємно і робить це для мене M-;.

Якщо мова підтримує однорядкові коментарі, а не на основі С, я буду більше схильний використовувати однорядкові коментарі. Інакше я боюся, що зараз я взявся за звичку. Що не обов'язково погано, оскільки воно змушує мене бути лаконічним.

Багаторядкові коментарі

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

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

Якщо це дійсно потрібно, то я б прокоментував inline, використовуючи те, що я згадував раніше, для останнього коментаря, якщо є сенс використовувати його у позиції. На особливому зворотному випадку, наприклад, або до документа 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 та ін.

Зазвичай я використовую їх у методах та класах для документування версій, що вводять функцію (або змінюють її), особливо якщо це для загальнодоступного API, та для надання деяких прикладів (із чіткими вхідними та вихідними справами та спеціальними випадками). Хоча в деяких випадках одиничний випадок може бути краще документувати, одиничні тести не обов'язково читаються людиною (незалежно від того, що DSL-річ ви використовуєте).

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

Коментований код

Я використовую однорядкові лише з однієї причини, мовою, схожою на C (за винятком випадків, коли компілюються для суворого C, де я їх справді не використовую): для коментування матеріалів під час кодування. Більшість IDE матимуть перемикач для однорядкових коментарів (вирівнювання за відступом або стовпцем 0), і це відповідає справжньому випадку для мене. Використання перемикача для багаторядкових коментарів (або вибору в середині рядків для деяких ІДЕ) ускладнить легко перемикатися між коментарями / коментарями.

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

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

Я, як правило, пишу:

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

Примітка про грамотне програмування

Можливо, ви захочете зацікавитись грамотним програмуванням , як його представив Дональд Кнут .

Грамотна парадигма програмування [...] являє собою відхід від написання програм у порядку та порядку, накладених комп’ютером, і натомість дає можливість програмістам розробляти програми в порядку, який вимагає логіка та потік їх думок. 2 Грамотні програми написані як безперебійна експозиція логіки у звичайній людській мові, подібно до тексту есе [...].

Інструменти грамотного програмування використовуються для отримання двох представлень з грамотного вихідного файлу: одне, яке підходить для подальшої компіляції чи виконання комп'ютером, "заплутаний" код, а інше для перегляду у форматованій документації, яку, як кажуть, "сплетено" грамотне джерело.

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


Це особисті умовності. Так, я можу бути дивним (і ти можеш теж бути). Це нормально, якщо ви дотримуєтесь кодових норм вашої команди під час роботи з однолітками або не радикально атакуйте їхні уподобання та приємно співіснуйте . Це частина вашого стилю, і ви повинні знайти тонку межу між розвитком стилю кодування, який визначає вас як кодер (або як послідовник школи думки чи організації, з якою ви маєте зв'язок) та дотриманням конвенції групи щодо послідовності. .


+1 для розрізнення коментованого коду від коментарів до документації. Я ненавиджу полювання на тих, хто вниз: P
deltreme

@deltreme: спасибі Я відчуваю твій біль, я полюю купу тих самих і в моєму поточному продукті. Існує СДЄ через ... Я дуже спокуса просто використовувати повнотекстовий пошук з регулярними виразами в Eclipse , або Emacs і просто знищити їх одного за іншим ... У мене є більш продуктивні речі , щоб зробити, до жаль :(
haylem

Будь ласка, дивіться цю відповідь щодо використання тегів дій чи завдань у коментарях .
haylem

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

має бути

// 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 та підтримуйте його відповідно.
хайлем

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

Я не люблю витрачати свій час на складання та розгортання коду. Я погодився б на ваш аргумент commodore, якщо байти матимуть одну перевагу, але вони не мають. Якщо ваш редактор не має виділення коду, перейдіть, придбайте собі 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. Виберіть систему документації, наприклад доксиген, і дотримуйтесь її. Продовжуйте перевіряти виготовлені документи.
  2. Спробуйте зобразити когось нового в кодовій базі, який приходить і читає ваші документи, чи можуть вони почати з цього запуску? Стажери насправді хороші для цього, сядьте нового вниз із вашою існуючою базою документів і простим завданням і подивіться, як далеко вони дістаються, якщо вони спотикаються, будьте впевнені, що все, що ви їм сказали, щоб їх знову вирушили, йде в документи.
  3. Зробіть зауваження щодо документації контрольною точкою в процесі огляду.

1

Читачі кодів зазвичай намагаються відповісти на три питання:

  1. Що робить цей клас чи функція? Якщо на це важко відповісти, то це занадто багато. Код, який важко документувати, зазвичай просто неправильний.
  2. Як я ним користуюся? Приклад може бути досить хорошим.
  3. Цей код дивує. Чому ти це зробив? Найімовірніші відповіді: обійти помилку в сторонніх компонентах, оскільки очевидна техніка виявилася занадто повільною

Все інше повинно бути виражене в коді. Як і написання прози, це мистецтво і вимагає багато практики. Єдиний спосіб зрозуміти, чи зрозумілий ваш код, - це змусити когось іншого прочитати його. Коли вони чогось не розуміють, не пояснюйте це усно. Удосконалити код. Додайте коментарі в крайньому випадку.

Якщо я побачу "подвійну довжину", я запитаю "Що таке одиниця виміру?" Не додайте коментарів. Змініть ім'я змінної. Якщо я бачу блок коду і кажу "що це робить?", Не додайте коментарів. Витягніть функцію зі змістовною назвою. Якщо ви не можете витягти функцію, оскільки для цього знадобиться 17 аргументів, перефактуруйте код.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.