Что не так с комментариями, которые объясняют сложный код?

Многие утверждают, что «комментарии должны объяснять« почему », но не« как ». Другие говорят, что «код должен быть самодокументированным», а комментарии должны быть недостаточными. Роберт К. Мартин утверждает, что (перефразировал мои собственные слова) часто «комментарии извиняются за плохо написанный код».

Мой вопрос следующий:

Что не так с объяснением сложного алгоритма или длинной и запутанной части кода с описательным комментарием?

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

Английский язык «разработан», чтобы его легко понять. Java, Ruby или Perl, однако, были разработаны для сбалансирования удобочитаемости и удобочитаемости компьютера, что ухудшает удобочитаемость текста. Человек может понять кусок английского языка намного быстрее, чем он может понять кусок кода с тем же значением (пока операция не является тривиальной).

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

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

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

Неужели так сложно объяснить сложный алгоритм с несколькими строками комментариев об общей работе? Что не так с объяснением сложного кода с комментарием?

226 голосов | спросил Aviv Cohn 1 stEurope/Moscowp30Europe/Moscow09bEurope/MoscowMon, 01 Sep 2014 04:28:12 +0400 2014, 04:28:12

16 ответов


399

В терминах непрофессионала:

  • В комментариях нет ничего плохого.
  • Что не так, это писать код, который нуждается в таких комментариях.
  • Что не так, при условии, что это нормально, чтобы написать сложный код, если вы объясните его дружелюбно на простом английском языке.
  • Комментарии не обновляются автоматически при изменении кода. Вот почему часто комментарии не синхронизируются с кодом.
  • Комментарии не делают код более легким для тестирования.
  • Извинение не плохо. То, что вы делали, требует извинения, плохо.
  • Программист, способный писать простой код для решения сложной задачи, лучше, чем тот, который пишет сложный код, а затем пишет длинный комментарий, объясняющий, что делает его код.

Нижняя строка:

Объяснение себя хорошо, не нужно делать это лучше.

ответил Tulains Córdova 1 stEurope/Moscowp30Europe/Moscow09bEurope/MoscowMon, 01 Sep 2014 04:52:56 +0400 2014, 04:52:56
106

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

Однако есть случаи, когда наилучшим выбором является наилучший выбор.

  • Если это сам алгоритм является сложным и запутанным, а не только его реализация - тот, который записывается в математических журналах и когда-либо упоминается как алгоритм Mbogo. », То вы добавили комментарий в самом начале реализации, прочитав что-то вроде« Это алгоритм Mbogo для refrobnicating widgets, изначально описанный здесь: [URL of paper]. Эта реализация содержит уточнения Алисы и Кэрол [URL другой статьи] «. Не пытайтесь вдаваться в подробности, чем это; если кому-то нужно больше деталей, им, вероятно, необходимо прочитать всю бумагу.

  • Если вы взяли что-то, что может быть написано в виде одной или двух строк в некоторых специализированных обозначениях, и расширили его в большой глобус императивного кода, помещая эти одну или две строки специализированной нотации в комментарий выше, это функция хороший способ рассказать читателю, что делать . Это исключение из «но что, если комментарий выходит из синхронизации с аргументом кода», потому что специализированная нотация, вероятно, much позволяет легче найти ошибки, чем код. (Это наоборот, если вы написали спецификацию на английском языке.) Хороший пример: https://dxr.mozilla.org/mozilla-central/source/layout/style/nsCSSScanner.cpp#1057 ...

    /**
     * Сканировать маркер юникодного диапазона. Они соответствуют регулярному выражению
     *
     * u \ + [0-9a-f?] {1,6} (- [0-9a-f] {1,6})?
     *
     * Однако некоторые такие жетоны являются «недействительными». Существуют три допустимые формы:
     *
     * u + [0-9a-f] {x} 1 <= x <= 6
     * u + [0-9a-f] {x} \? {y} 1 <= x + y <= 6
     * u + [0-9a-f] {x} - [0-9a-f] {y} 1 <= x <= 6, 1 <= y <= 6
    
  • Если код является простым в целом, но содержит одну или две вещи, которые выглядят чрезмерно запутанными, ненужными или просто ошибочными, но должны быть именно так из-за причин, то вы помещаете комментарий непосредственно над подозрительным битом, в котором вы укажите причины . Вот простой пример, где единственное, что нужно объяснить, - это то, почему константа имеет определенное значение.

    /* s1 * s2 <= SIZE_MAX, если s1 <K и s2, K, где K = sqrt (SIZE_MAX + 1) * /
    const size_t MUL_NO_OVERFLOW = ((size_t) 1) <(sizeof (size_t) * 4);
    if ((nmemb> = MUL_NO_OVERFLOW || size> = MUL_NO_OVERFLOW) & & & &
        nmemb> 0 & & SIZE_MAX /nmemb <размер)
      прервать ();
    
ответил zwol 1 stEurope/Moscowp30Europe/Moscow09bEurope/MoscowMon, 01 Sep 2014 06:35:30 +0400 2014, 06:35:30
59
  

Итак, что не так с объяснением сложного кода с комментарием?

Речь идет не о правильном или неправильном, а о «лучшей практике», как определено в статье Википедии :

  

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

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

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

ответил FMJaguar 1 stEurope/Moscowp30Europe/Moscow09bEurope/MoscowMon, 01 Sep 2014 05:25:14 +0400 2014, 05:25:14
52

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

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

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

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

Поэтому я не думаю о комментариях как об извинениях за плохой код, но, возможно, в качестве объяснения того, почему вы не сделали очевидной вещи. Имея //Стандартный подход не работает против 64-битной версии библиотеки Frobosticate, позволит будущим разработчикам, включая ваше будущее, обращать внимание на эту часть кода и протестировать эту библиотеку , Конечно, вы можете поместить комментарии в свой контрольный элемент управления тоже, но люди будут смотреть на них только после того, как что-то пошло не так. Они будут читать комментарии кодов, поскольку они меняют код.

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

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

ответил glenatron 1 stEurope/Moscowp30Europe/Moscow09bEurope/MoscowMon, 01 Sep 2014 14:47:22 +0400 2014, 14:47:22
29

Потребность в комментариях обратно пропорциональна уровню абстракции кода.

Например, язык сборок для большинства практических целей непонятен без комментариев. Вот выдержка из маленькой программы, которая вычисляет и печатает термины серии Фибоначчи :

 main:
; инициализирует два числа и счетчик. Обратите внимание, что это предполагает
; что области счетчика и num1 и num2 смежны!
;
    mov ax, '00 '; инициализировать все нули ASCII
    mov di, counter; включая счетчик
    mov cx, цифры + cntDigits /2; по два байта за раз
    cld; инициализировать от низкой до высокой памяти
    репутация; написать данные
    inc ax; убедитесь, что ноль ASCII равен
    mov [num1 + цифры - 1], al; последняя цифра - одна
    mov [num2 + цифры - 1], al;
    mov [counter + cntDigits - 1], al

    jmp .bottom; выполняется с инициализацией, поэтому начните

.Вверх
    ; добавьте num1 в num2
    mov di, num1 + digit-1
    mov si, num2 + digit-1
    mov cx, цифры;
    вызовите AddNumbers; num2 + = num1
    mov bp, num2;
    вызовите PrintLine;
    dec dword [term]; счетчик контуров декремента
    jz .done;

    ; добавьте num2 в num1
    mov di, num2 + digit-1
    mov si, num1 + digit-1
    mov cx, цифры;
    вызовите AddNumbers; num1 + = num2
.дно
    mov bp, num1;
    вызовите PrintLine;
    dec dword [term]; счетчик контуров декремента
    jnz .top;
.сделанный
    вызов CRLF; завершать CRLF
    mov ax, 4c00h; прекратить
    int 21h;

Даже с комментариями это может быть довольно сложно.

Современный пример: регулярные выражения часто представляют собой очень низкие конструкции абстракции (строчные буквы, цифры 0, 1, 2, новые строки и т. д.). Вероятно, им нужны комментарии в виде образцов (Боб Мартин, IIRC, признает это). Вот регулярное выражение, которое (я думаю) должно соответствовать HTTP (S) и URL-адресам FTP:

 ^ (((ht | f) tp (s?)) \: //)? (www. | [a-zA-Z].) [ A-Za-Z0-9 \ - \] + \ (обыкн | образование | гов | м..
+ Иль | чистый | орг | бизнес | Информация | Название | Музей | нас | ча | ик) (\: [0-9] +) * (/($ | [A-Za-Z0-9 \.
? + \, \; \ \ '\\\ + & амп; амп;% \ $ # \ = ~ _ \ -] +)) * $

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

Я думаю о Numerical Recipes в C , переведенном в основном дословно на Numerical Recipes в C ++ , который я делаю, начиная с Numerical Recipes (в FORTAN) со всеми переменными a, aa, b, c, cc и т. д., поддерживаемые каждой версией. Алгоритмы, возможно, были правильными, но они не воспользовались абстракциями предоставленных языков. И они меня отпустили. Образец из статьи доктора Доббса - быстрое преобразование Фурье :

 void four1 (double * data, unsigned long nn)
{
    unsigned long n, mmax, m, j, istep, i;
    double wtemp, wr, wpr, wpi, wi, theta;
    double tempr, tempi;

    //обратное двоичное переиндексация
    n = nn <1;
    J = 1;
    для (i = 1; i <n; i + = 2) {
        если (j> i) {
            swap (данные [j-1], данные [i-1]);
            swap (данные [j], данные [i]);
        }
        m = nn;
        в то время как (m> = 2 & j> m) {
            j - = m;
            m> = 1;
        }
        j + = m;
    };

    //здесь начинается раздел Дэниелсона-Ланцоша
    Mmax = 2;
    в то время как (n> mmax) {
        istep = mmax <1;
        theta = - (2 * M_PI /mmax);
        wtemp = sin (0,5 * theta);
        wpr = -2.0 * wtemp * wtemp;
        wpi = sin (theta);
        wr = 1,0;
        wi = 0,0;
        для (m = 1, m <mmax; m + = 2) {
            для (i = m; i <= n; i + = istep) {
                J = я + Mmax;
                tempr = wr * data [j-1] - wi * data [j];
                tempi = wr * data [j] + wi * data [j-1];

                данные [j-1] = данные [i-1] - tempr;
                данные [j] = данные [i] - tempi;
                данные [i-1] + = tempr;
                данные [i] + = tempi;
            }
            wtemp = WR;
            wr + = wr * wpr - wi * wpi;
            wi + = wi * wpr + wtemp * wpi;
        }
        Mmax = Истэп;
    }
}

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

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

ответил Kristian H 2 ndEurope/Moscowp30Europe/Moscow09bEurope/MoscowTue, 02 Sep 2014 19:42:05 +0400 2014, 19:42:05
19

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

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

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

ответил Roy 1 stEurope/Moscowp30Europe/Moscow09bEurope/MoscowMon, 01 Sep 2014 18:10:49 +0400 2014, 18:10:49
18

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

  

Что не так с объяснением (1) сложного алгоритма или (2) длинным и запутанным фрагментом кода с описательным комментарием?

(1) неизбежно. Я не думаю, что Мартин не согласился бы с вами. Если вы пишете что-то вроде быстрого обратного квадратного корня , вам понадобятся некоторые комментарии , даже если это просто «злоумышленный взлом». Запрещая что-то простое, как DFS или двоичный поиск, маловероятно, что человек, читающий ваш код, будет иметь опыт работы с этим алгоритмом, и поэтому я думаю, что в комментариях должно быть хотя бы упоминание о том, что это такое.

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

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

  

Не комментируйте неправильный код - перепишите его.

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

И это именно то, что говорит Мартин:

  

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

Это ваш (2). Мартин соглашается с тем, что длинный, сложный код нуждается в комментариях, но он ставит вину за этот код на плечи программиста, который написал его, а не туманную идею, что «мы все знаем, что этого недостаточно». Он утверждает, что:

  

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

ответил Patrick Collins 1 stEurope/Moscowp30Europe/Moscow09bEurope/MoscowMon, 01 Sep 2014 06:53:27 +0400 2014, 06:53:27
8
  

Что не так с объяснением сложного алгоритма или длинной и запутанной части кода с описательным комментарием?

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

Тем не менее, у вас есть ложная дихотомия: писать чистый код и писать документированный код - эти два не противоречат.

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

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

  

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

True. Вот почему все ваши общедоступные API-алгоритмы должны быть объяснены в документации.

  

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

В идеале, после написания сложной части кода вы должны (не исчерпывающий список):

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

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

  

[...] некоторые алгоритмы сложны. И поэтому их трудно понять, читая их по строкам.

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

  

Неужели так сложно объяснить сложный алгоритм с несколькими строками комментариев об общей работе?

Нет - это хорошо. Однако добавить несколько строк комментариев недостаточно.

  

Что не так с объяснением сложного кода с комментарием?

Тот факт, что у вас не должно быть сложного кода, если этого можно избежать.

Чтобы избежать сложного кода, формализуйте свои интерфейсы, потратите ~ 8 раз больше на разработку API, чем потратите на реализацию (Степанов предложил потратить не менее 10 раз на интерфейс, по сравнению с реализацией) и перейти к разработке проекта с помощью знание о том, что вы создаете проект, а не просто написать некоторый алгоритм.

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

ответил utnapistim 1 stEurope/Moscowp30Europe/Moscow09bEurope/MoscowMon, 01 Sep 2014 16:33:03 +0400 2014, 16:33:03
6
  

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

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

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

  • Комментарии не обязательно верны, тогда как код делает то, что он делает. Поэтому читатель берет ваше слово за это, и это не идеально.
  • Читатель еще не понимает сам код, поэтому, пока они не вернутся к нему, они все еще не имеют права изменять или повторно использовать его. В этом случае, что они читают?

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

ответил Steve Jessop 1 stEurope/Moscowp30Europe/Moscow09bEurope/MoscowMon, 01 Sep 2014 12:41:55 +0400 2014, 12:41:55
5

Часто нам приходится делать сложные вещи. Конечно, правильно документировать их для будущего понимания. Иногда правильное место для этой документации содержится в коде, где документация может быть обновлена ​​с кодом. Но определенно стоит рассмотреть отдельную документацию. Это также может быть проще представить другим людям, включая диаграммы, цветные изображения и т. Д. Тогда комментарий просто:

//Этот код реализует алгоритм, описанный в документе требований 239.

или даже просто

void doPRD239Algorithm () {...

Конечно, люди довольны функциями с именем MatchStringKnuthMorrisPratt или encryptAES или partitionBSP. Более неясные имена заслуживают объяснения в комментарии. Вы также можете добавить библиографические данные и ссылку на документ, из которого вы реализовали алгоритм.

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

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

/* Настройте контроллер луча и включите лазер.
Последовательность является критической по времени, и этот код должен работать с отключенными прерываниями.
Обратите внимание, что константа 0xef45ab87 отличается от документации поставщика; поставщик
в этом случае не так.
Некоторые из этих операций записывают одно и то же значение несколько раз. Не пытайтесь
для оптимизации этого кода путем удаления, казалось бы, избыточных операций.
* /
ответил pjc50 1 stEurope/Moscowp30Europe/Moscow09bEurope/MoscowMon, 01 Sep 2014 18:50:13 +0400 2014, 18:50:13
5

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

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

Например:

//Геттер.
public <V> V get (конечный ключ K, тип класса <V>) {
  //Он еще запущен?
  Будущее & л; Объект > f = multitons.get (ключ);
  if (f == null) {
    //Нет! Сделайте задачу, которая ее запускает.
    FutureTask & л; Объект > ft = new FutureTask <Object> (
            new Callable () {

              public Object call () throws Exception {
                //Делаем только созданный при вызове.
                return key.create ();
              }

            });
    //Только поставить, если нет.
    f = multitons.putIfAbsent (key, ft);
    if (f == null) {
      //Мы заменили null, чтобы мы успешно положили. Мы были первыми!
      f = ft;
      //Инициируем задачу.
      ft.run ();
    }
  }
  пытаться {
    /**
     * Если код попадает сюда и зависает из-за f.status = 0 (FutureTask.NEW)
     * то вы пытаетесь получить от своего Multiton в своем создателе.
     *
     * Невозможно проверить это без излишне сложного кода.
     *
     * Возможно, можно использовать get с таймаутом.
     * /
    //Приведение сюда, чтобы заставить правильный тип.
    return (V) f.get ();
  } catch (Exception ex) {
    //Скрыть исключения, не отбрасывая их.
    throw Throwables.asRuntimeException (ex);
  }
}

Здесь нет попытки указать, что делает каждый шаг, все, что он заявляет, это то, что нужно .

PS: Я нашел источник, о котором я говорил, - Ужас кодирования: Код говорит вам, как, комментарии говорят вам, почему

ответил OldCurmudgeon 1 stEurope/Moscowp30Europe/Moscow09bEurope/MoscowMon, 01 Sep 2014 15:06:20 +0400 2014, 15:06:20
4
  

Но мы все знаем, что этого недостаточно.

Действительно? Поскольку, когда?

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

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

ответил Telastyn 1 stEurope/Moscowp30Europe/Moscow09bEurope/MoscowMon, 01 Sep 2014 04:57:21 +0400 2014, 04:57:21
2

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

При этом комментарии в источнике являются одной из форм документации для других программистов (включая вас самих). Если комментарии касаются более абстрактных проблем, чем то, что делает код на каждом шагу, вы делаете лучше, чем в среднем. Этот уровень абстракции зависит от используемого вами инструмента. Комментарии, сопровождающие процедуры ассемблерного языка, обычно имеют более низкий уровень абстракции, чем, например, этот APL Aâ † 0a <"A⊠£ {2⊤â μ: 1 + 3Ã-â μâ <" â μà · 2} â £ {â º = A + â † 1} ⎠• . Я думаю, что это, вероятно, заслуживает комментария о проблеме, которую оно предназначено для решения, хммм?

ответил Scott Leadley 1 stEurope/Moscowp30Europe/Moscow09bEurope/MoscowMon, 01 Sep 2014 06:12:22 +0400 2014, 06:12:22
2

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

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

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

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

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

ответил Martin 1 stEurope/Moscowp30Europe/Moscow09bEurope/MoscowMon, 01 Sep 2014 17:00:07 +0400 2014, 17:00:07
0

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

f1 = (float) (f2 + f3); //Принудительный результат округляется до одинарной точности
f4 = f1-f2;

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

вещь.someFloatProperty = (float) (f2 * 0,1); //Разделить на десять

Здесь цель броска состоит в том, чтобы предотвратить компромисс от крики наиболее эффективным способом точного вычисления (f2 /10) [он более точен, чем умножать на 0,1f, и на большинстве машин он быстрее, чем деление на 10.0 е].

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

ответил supercat 1 stEurope/Moscowp30Europe/Moscow09bEurope/MoscowMon, 01 Sep 2014 19:35:24 +0400 2014, 19:35:24
-1

Комментарии, которые объясняют, что делает код, являются формой дублирования. Если вы измените код и затем забудьте обновить комментарии, это может вызвать путаницу. Я не говорю, что не использую их, просто используйте их разумно. Я подписываюсь на «Дядя Боб»: «Только комментируйте, что код не может сказать».

ответил murungu 7 FebruaryEurope/MoscowbSat, 07 Feb 2015 15:36:36 +0300000000pmSat, 07 Feb 2015 15:36:36 +030015 2015, 15:36:36

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132