Комментарии — ложь
Если вы программист, то есть много практик, которые можно ненавидеть.
Жестко запрограммированные значения. Двойная логика. Сложные иерархии наследования. Но должны ли входить комментарии в этом списке?
Давным-давно, во времена доисторического программирования, писать комментарии считалось обязательной составляющей написания кода. Когда вы писали код, его наполняли короткие и точные комментарии. Затем чистый код и agile программирование стали править миром. Пуристы кричали о вреде комментариев, которые наполняли неструктурированный и уязвимый код. Внезапно комментарии стали ошибкой, антипаттерном, сборниками откровенной лжи.
Многие разработчики почувствовали себя загнанными в угол.
Ложный выборНо так ли очевиден выбор? Или же все-таки есть способ писать комментарии и при этом уважать себя, вставая утром? Чтобы узнать ответ, давайте рассмотрим, как комментируют ужасный код и как даже плохой комментарий может спасти жизни.
Ленивые комментарии
Самая частая ошибка, которую совершают разработчики, это комментирование кода вместо написания хорошего кода.
Например, возьмем этот фрагмент кода, взятый из реального приложения:
double delta = h*h-r1*r1;
double r2 = Math.Sqrt(delta);
Несмотря на то, что кодовые операции в этом фрагменте легко понять, значение кода неясно. Но разработчик, который написал такой непонятный код, может быстро скрыть его низкое качество, добавив поясняющий комментарий:
// Calculate side length using the Pythagorean Theorem
// and put the value into variable "r2"
double delta = h*h-r1*r1;
double r2 = Math.Sqrt(delta);
Это первая проблема с комментариями — они открывают дверь вредным привычкам. Они соблазняют вас сойти с дороги непрерывного рефакторинга на простой путь описания небрежного кода.
В этом примере есть много способов избежать комментария. Вот один из возможных вариантов, где все нужное говорят имена переменных:
double lengthSideB = Math.Sqrt(
Math.Pow(hypotenuse,2) - Math.Pow(lengthSideA,2);
)
Или вы можете вынести операцию в отдельный метод и назвать метод должным образом:
double sideA = Pythagoras.GetLengthOfSide(hyptenuse, sideB);
Не перебор ли это для такого простого примера? Очевидно! Но этот пример иллюстрирует одну из основных стратегий чистого кодирования — извлечь смысл из комментария и вставить его в имена переменных, методов, классов и интерфейсов. Ленивые комментарии используются не только для того, чтобы избежать рефакторинга. Они также используются, чтобы не обдумывать проблему или не завершать работу. Особенно плохое использование комментария — это документирование странного поведения в программе кода без каких-либо попыток исправить это.
Ложные комментарии
Для многих сторонников чистого кодирования недостаточно просто избавиться от ленивых комментариев. Даже комментарии, которые кажутся невинными, представляют собой риск, потому что они могут противоречить реальности вашего кода. Другими словами, комментарии представляют собой тип дублирования — человеческое повторение компьютерно-языкового решения. Это означает, что они подвержены несогласованности, как и дублированный код в вашем приложении. Другой программист может изменить программный код, забыв изменить комментарии. Это особенно вероятно, когда комментарий применяется к длинным блокам кода или находится не рядом с реализацией. Разработчики особенно неаккуратны с таким случаем:
/**
* Constructor.
*
* @param name (required) brand name of the product. Must have
* content. Length must be in range 1..50.
* @param price (optional) purchase price of the product.
* @param units (required) number of units currently in stock.
* Can not be less than 0.
*/
public Product(string name, decimal price, integer units)
{
...
}
Некоторые компании поддерживают эти блоки комментариев, полагая, что больше информации означает меньше двусмысленности. Это верно — до тех пор, пока блок комментариев не будет скопирован и вставлен слишком много раз и не станет источником неверной информации. Ложные комментарии создают ловушку последующих за ними разработчиков. Поверьте ошибочному комментарию, и вы начнете цепочку неверных предположений, которые могут привести к игнорированию существующей ошибки или даже к новой.
Все врет
Комментарии не заслуживают доверия. Вы не найдете модульных тестов, которые могли бы гарантировать их истинность. Но это не уникальная проблема. На самом деле почти все может лгать. Типичный проект кодирования повторяется во многих различных областях. Есть требования к архитектуре, документация, схема данных — все это может противоречить друг другу. Рассмотрим документацию API. Вы можете создать его со всеми нужными типами, членами и сигнатурами методов, используя рефлексию. Здесь нет возможности солгать. Но после этого кто-то должен написать описания, которые придают смысл этим структурам кода. Тот факт, что документация API может лгать, является разочарованием для разработчиков, работающих с быстро меняющимися технологиями, но это вряд ли повод отказываться от них. С документацией проблемы не заканчиваются. Даже если вы замените каждый комментарий тщательно названными переменными и именами методов, эти имена также могут быть превращены в ложь из-за неосторожного редактирования. Другими словами, риск поверить в комментарий реален. Но не путайте риск использования ложного комментария с риском его написания.
«Комментарии — ложь» — говорит нам перестать доверять комментариям, а не писать их.
Комментарии не бесполезны
Даже неправильный комментарий не обязательно бесполезный. Рассмотрим следующий загадочный комментарий, который остался в открытом коде моей любимой ритм-игры более десяти лет назад:
// to match ITG1's late arrows. -K
GlobalOffsetSeconds=-0.006
Этот комментарий заслужил дурную репутацию, потому что он в точности не соответствует действительности — отрицательное смещение сдвигает синхронизацию песни раньше, а не позже. И все же этот явно неверный комментарий по-прежнему содержит информацию, раскрывающую проблему, которую разработчики игр пытались исправить, и ошибочное решение, которое они приняли. Что еще более важно, это дает вам представление о том, как вы можете исправить то, что пошло не так. Или представьте пример с регулярными выражениями. Если вы добавили его в свой код, надеюсь, вы добавили комментарий, объясняющий его назначение. Но что, если ваш комментарий лжет — другими словами, регулярное выражение не проверяет должным образом то, что, по вашему мнению, оно делает? В этом случае ваш комментарий по-прежнему имеет ценность, потому что он записывает ваше намерение, а это единственная информация, которую разработчик, исправляющий вашу ошибку, должен будет получить.
Очевидно, что комментарий, проливающий частичный свет на проблему, уступает чистому, идеальному коду. Но не все разработчики пишут чистый код, и большинство разработчиков, которым это удается, не всегда добиваются идеальных результатов. Трудно поставить себя на место другого человека, читающего вашу работу. Очевидное для одного человека — непонятное для другого, и этот человек — вы в следующем году.
«I spent some time this weekend looking at very well-named, very clean, uncommented code implementing a research algorithm. I«m high-level familiar with it, the guy sitting next to me was the inventor, and the code was written a few years ago by someone else. We could barely follow it.» — Paul Nathan
Меняются продукты, меняются стандарты, компании прогресирую. Контекст, в котором рассматривается старый код, будет отличаться от контекста, в котором он был написан. Комментарии могут привести к описанию проверенных и неудачных попыток и предостеречь от неожиданных проблем. Они могут подсказать, что пошло не так. Возможно, в них нет необходимости, а может и нет. Но они могут быть подарком на будущее.
Комментарии представляют собой страховой полис
Да, есть цена за привнесение двусмысленности и возможной лжи в ваш код. Но есть также расходы на страхование дома или автомобиля. Мы можем снизить затраты на комментарии следующим образом:
Помните о плохих методах работы (ленивых комментариях и небрежном коде)
Осторожно относиться ко лжи (никому не доверять)
Управление мусорным комментарием (с помощью инструментов в среде IDE)
Главный вопрос прост. Стоит ли платить за комментарии? Мнения расходятся, но если вы используете комментарии вдумчиво и разумно — если вы используете их для уменьшения когнитивной нагрузки кода, а не для противодействия плохим практикам — они могут повысить ценность даже самого чистого кода.
Вот совершенно ненаучный опрос людей, прочитавших эту статью. Выберите утверждение, которое больше всего тронет ваше сердце!