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

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

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

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

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

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

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

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

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

Ответ 1

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

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

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

Ответ 2

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

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

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

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

Ответ 3

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

Ответ 4

Кто-то сказал

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

Ответ 5

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

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

Ответ 6

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

/* compute displacement with Newton 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);

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

Ответ 7

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

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

Ответ 8

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

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

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

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

Etc.

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

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

Ответ 9

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

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

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

Ответ 10

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

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

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)

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

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

Ответ 11

В порядке:

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

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

Ответ 12

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

/**
 * 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;
 }

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

Ответ 13

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

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

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

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

Ответ 14

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

Ответ 15

Слышали ли вы о проекте Donald Knuth "WEB", чтобы реализовать его концепцию Literate Programming? Это больше, чем самодокументирующий код; это больше похоже на документацию, которая может быть скомпилирована и выполнена как код. Я не знаю, сколько он используется сегодня.

Ответ 16

Разница между "чем" и "как".

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

Ответ 17

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

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

Ответ 18

Мое мнение написано в этом сообщении:

Один совет для документирования вашего кода.

Выдержки:

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

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

Ответ 19

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

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

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

Ответ 20

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

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

Ответ 21

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

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

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

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

Если вы можете найти книгу Кнута на ней в библиотеке (Дональд Э. Кнут, "Грамотное программирование", Стэнфорд, Калифорния: Центр изучения языка и информации, 1992, Лекционные заметки CSLI, № 27.), вы должны прочитать он.

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

Ответ 22

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

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

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

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

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

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

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

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

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

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

Ответ 23

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

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

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

Ответ 24

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

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

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

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

Ответ 25

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

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

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

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

Ответ 26

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

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

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

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

Ответ 27

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

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

Ответ 28

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

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

Ответ 29

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

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

BisectionSearch

BinarySearch

BinaryChop

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

Ответ 30

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

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

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

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

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