Что такое самодокументируемый код и может ли он заменить хорошо документированный код? [закрытый]

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

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

помогите мне понять его точки зрения.

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

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

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

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

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

30 ответов


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

  • пишет комментарии к документации (Doxygen, JavaDoc, XML-комментарии и т. д.) для каждого класса, члена, типа и метода и
  • четко комментарии любые части кода, которые являются не самодокументирование и
  • пишет комментарий для каждого блока кода, который объясняет цель, или то, что код делает на более высоком уровне абстракции (т. е. найти все файлы размером более 10 МБ вместо цикл через все файлы в каталоге, проверить, если размер файла больше, чем 10 МБ, доходность, если true)

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


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

float a, b, c; a=9.81; b=5; c= .5*a*(b^2);

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

const float gravitationalForce = 9.81;
float timeInSeconds = 5;
float displacement = (1 / 2) * gravitationalForce * (timeInSeconds ^ 2)

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

/* compute displacement with Newton's equation x = vₒt + ½at² */
const float gravitationalForce = 9.81;
float timeInSeconds = 5;
float displacement = (1 / 2) * gravitationalForce * (timeInSeconds ^ 2)

и окончательная версия код как документацию с нулевыми комментариями:

float computeDisplacement(float timeInSeconds) {
    const float gravitationalForce = 9.81;
    float displacement = (1 / 2) * gravitationalForce * (timeInSeconds ^ 2)
    return displacement;
}

вот пример плохого стиля комментирования:

const float a = 9.81; //gravitational force
float b = 5; //time in seconds
float c = (1/2)*a*(b^2) //multiply the time and gravity together to get displacement.

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

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


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


кто-то однажды сказал

1) Пишите комментарии только для кода, который трудно понять.
2) Старайтесь не писать код, который трудно понять.


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

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


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

/* compute displacement with Newton's equation x = v0t + ½at^2 */
const float gravitationalForce = 9.81;
float timeInSeconds = 5;
float displacement = (1 / 2) * gravitationalForce * (timeInSeconds ^ 2);

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

const float accelerationDueToGravity = 9.81;
float timeInSeconds = 5;
float displacement = NewtonianPhysics.CalculateDisplacement(accelerationDueToGravity, timeInSeconds);

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


Я забыл, откуда я это взял, но:

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


Самодокументированный код является хорошим примером "Сухого" (не повторяйтесь). Не дублируйте информацию в комментариях, которая есть или может быть в самом коде.

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

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

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

Etc.

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

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


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

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

self-documenting code + необходимые комментарии пройдут долгий путь к помощи людям в разных командах.


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

Самодокументирующийся код-это код, который не требует комментариев свободного текста для информированного читателя, чтобы понять, что он делает. Например, этот фрагмент кода является самодокументирующимся:

print "Hello, World!"

и вот это:

factorial n = product [1..n]

и так вот:

from BeautifulSoup import BeautifulSoup, Tag

def replace_a_href_with_span(soup):
    links = soup.findAll("a")
    for link in links:
        tag = Tag(soup, "span", [("class", "looksLikeLink")])
        tag.contents = link.contents
        link.replaceWith(tag)

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


по порядку:

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

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


например, рассмотрим следующий фрагмент:

/**
 * Sets the value of foobar.
 *
 * @foobar is the new vaue of foobar.
 */
 public void setFoobar(Object foobar) {
     this.foobar = foobar;
 }

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

Если конечно, лучшей версией было бы:

/**
 * The serialization of the foobar object is used to synchronize the qux task.
 * The default value is unique instance, override if needed.
 */
 public void setFoobar(Object foobar) {
     this.foobar = foobar;
 }

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


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

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

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

просто щепотка соли...


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


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


разница между "что" и "как".

  • вы должны документировать" то, что " делает подпрограмма.
  • вы не должны документировать "как" это делает, если только особые случаи (например, обратитесь к конкретному документу алгоритма). Это должно быть задокументировано.

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

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


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

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


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

однако такой "самодокументирующий код" никогда не заменит комментарии. Иногда код слишком сложен, и самодокументирующегося кода недостаточно, особенно в плане ремонтопригодности.

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


Я удивлен, что никто не привел "Грамотное Программирование", метод, разработанный в 1981 году Дональдом Э. кнутом из TeX и" искусство компьютерного программирования " славы.

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

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

Я нашел пример в интернете:http://moonflare.com/code/select/select.nw или версия HTML http://moonflare.com/code/select/select.html

Если вы можете найти книгу кнута об этом в библиотеке (Donald E. Knuth, Literate Programming, Stanford, California: Center for the Study of Language and Information, 1992, CSLI Lecture Notes, no. 27. вы должны прочитать его.

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


мой взгляд написан в этом посте:

один единственный совет для документирования кода.

выдержка:

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

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


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

Что такое исходный код? Что такое язык программирования?

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

должны ли вы уметь читать то, что вы пишете?

исходный код не записывается в человеческий язык. Он был опробован (например, FORTRAN), но он не совсем успешен.

исходный код не может быть двусмысленности. Вот почему мы должны поместить в него больше структуры, чем в текст. Текст работает только с контекстом, который мы принимаем как должное, когда мы используем текст. Контекст в исходном коде всегда explisit. Подумайте об "использовании" в C#.

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

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

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

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


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

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

  • код должен быть максимально прост и понятен читайте как можно больше.
  • комментарии должны давать объяснения дизайнерские решения я принимала, типа: почему использую ли я этот алгоритм, или ограничения код имеет, как: делает не работать когда ... (это должно быть обрабатывается в контракте / утверждении в код) (обычно в рамках функции / процедуры).
  • документация должна перечислить использование (называя converntions), боковые эффекты, возможные возвращаемые значения. Он можно извлечь из кода с помощью такие инструменты, как jDoc или xmlDoc. Он поэтому, как правило, находится за пределами функция / процедура, но близко к код, который он описывает.

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


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

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

будучи в состоянии определить, что код делает X с быстрого взгляда, намного проще, чем определить, что код не делает Y. Он должен документировать Y...

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


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

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

Edit: я (и, вероятно, все остальные), вероятно, должен иметь положение, что приложение цифровой обработки сигналов (DSP) должно быть очень хорошо прокомментировано. Это в основном потому, что приложения DSP по существу 2 для циклов, подаваемых с массивами значений и добавляет/умножает/и т.д. указанные значения... чтобы изменить программу, вы меняете значения в одном из массивов... нужно пару комментариев, чтобы сказать, что вы делаете в в этом случае;)


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

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

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

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


Я бы сказал - как и многие из вас, - что для того, чтобы быть по-настоящему самодокументированным, код должен показывать какую-то форму намерения. Но я удивлен, что никто еще не упомянул BDD - Развитие, Обусловленное Поведением. Часть идеи заключается в том, что у вас есть автоматические тесты (код), объясняющие намерение вашего кода, что так сложно сделать очевидным в противном случае.

Good domain modeling 
+ good names (variabes, methods, classes) 
+ code examples (unit tests from use cases) 
= self documenting software 

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

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

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

также имейте в виду разницу в вашей команде, если вы приезжаете из разных национальностей. Различия в дикции можете creap в наименовании методы:

BisectionSearch

BinarySearch

BinaryChop

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


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

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

public Result whatYouWantToDo(){
  howYouDoItStep1();
  howYouDoItStep2();
  return resultOfWhatYouHavDone;
}

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

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