Комментарии: за или против?

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

Читаемость не всегда в приоритете 

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

В мире программирования есть аналогичный случай, а именно программирование типа “bare metal” (“на голом железе”), применяемое в высокочастотном трейдинге, в режиме реального времени или похожих приложениях с акцентом на скорости и низком значении задержки. Например, вы можете заменить объекты и поля примитивными данными, упакованными в массивы, с возможностью распараллеливания этих данных и молниеносного их выполнения посредством параллельных CPU или GPU без совместного использования или конкуренции. 

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

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

Лагерь противников комментариев 

Как правило, все противники комментариев в коде приводят следующие доводы: 

  • Хороший код  —  это самодокументирующийся код. Если его нельзя понять при чтении, то он оставляет желать лучшего и подлежит перезаписи. К этой же категории относятся такие понятия, как корректные имена переменных и методов, простых алгоритмов и т. д. 
  • Зависимость кода от комментариев говорит о его несостоятельности: он либо доработан, либо плохо структурирован, и потому должен быть переписан. 
  • Поскольку со временем код претерпевает изменения, комментарии зачастую не обновляются и, следовательно, не синхронизируются. Комментарий, изначально пояснявший первичный вариант того, что делает код, устаревает и предоставляет ложное или ошибочное описание без учета внесенных корректив.  
  • В случае простого грамотно написанного кода комментарии просто дублируют то, что и так очевидно. Например, возьмем метод getter, комментарий к которому  —  “получает поле X” (“gets field X”)  —  просто излишен. 
  • Качество комментариев очень сильно отличается среди программистов. Кроме того, к ним не предъявляются такие строгие требования, как к исполняемому коду, а именно модульным тестам, pre-commit хукам или автоматическому анализу качества. 
  • Написание комментариев замедляет работу и отвлекает внимание от основной цели, требующий концентрации,  —  самого кода. 

Лагерь сторонников комментариев 

В поддержку комментариев звучат следующие аргументы: 

  • Комментарии выявляют цель кода. И наши размышления в разделе о читаемости отличный тому пример  —  в случае неочевидного кода комментарии раскроют его назначение в гораздо более удобочитаемом виде. 
  • Комментарии документируют бизнес-правила. Предположим, фрагмент кода выдает ответ 42, но в связи с чем  —  зачастую не понятно. Вероятно, тому существует какое-то логическое бизнес-обоснование, которое должно быть задокументировано в сохранном месте, где оно будет всегда под рукой, чтобы предотвратить ненамеренное нарушения установленного правила. И комментарии как раз идеально для этого подходят. 
  • Комментарии документируют процессы. По аналогии с предыдущим пунктом, если код придерживается процесса или последовательности шагов, то запросто можно описать каждый шаг и другие зависимости в более удобочитаемой форме. 
  • Генерация Javadoc, JSDoc и тому подобное. Комментарии, размещенные в методах, полях и классах, преобразуются в HTML-документы, предоставляемые для чтения в интернете и с доступом из IDE. Хорошо задокументированный код превращается в черный ящик, который можно уверенно использовать без необходимости обращаться к исходному коду для прояснения каких-то моментов (как будто распускаете нитку по краю свитера). Как нельзя лучше подходит для API. Уверен, вам случалось работать как с хорошо задокументированными и понятными API или библиотеками, так и с другими менее удачными аналогами, вследствие чего приходилось тратить много времени на отчаянные изучение, эксперименты и поиски. 
  • В целом по сравнению с кодом комментарии читаются быстрее и легче. Команда разработки может рассчитывать на грамотно написанные комментарии, поясняющие код в доступной манере, даже несмотря на его сложность. И пусть написание комментариев требует времени, зато читаются они гораздо быстрее, чем сопровождаемый ими код. 
  • Написание комментариев выявляет ошибки и предположения в ходе ваших мыслей. Довольно часто при их составлении, особенно в случае с Javadoc, мне становилось очевидно, что код не такой простой, как казалось на первый взгляд. Он может предполагать наличие предусловий, требовать конкретного формата данных, сбоить при определенных условиях или вызывать другие предположения. В процессе создания комментариев я размышляю над этими недостатками. Зачастую меня осеняет, и я меняю структуру нужного фрагмента кода для устранения недочетов, чего бы я не сделал, если бы дважды не сосредоточился на решении проблемы: первый раз  —  пока писал код, а второй  —  пока комментировал. 
  • Комментарии помогают следить за ходом мысли автора кода. И пусть сам код устарел, автор покинул организацию, или речь идет о заказчике, программирующем в отношении внешнего API. Комментарии выступают в качестве ответов на возникающие у вас вопросы. Они помогают освежить в памяти уже подзабытый было код, и я сам их не раз использовал именно с этой целью.

Назад к проблеме читаемости 

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

Дело в том, что нельзя просто сказать: “Пиши более читаемый, самодокументирующийся код”, поскольку это не всегда возможно. Когда-то существовала концепция, противопоставляющая “логическое” проектирование “физическому”, и мне кажется, комбинацию “код+комментарии” можно рассмотреть с этой точки зрения. Стремление приравнять логический уровень (т. е. намерение) к физическому (т. е. выполнение) только ради того, чтобы принципиально избавиться от комментариев, явно не пойдет на пользу производительности. 

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

Так…что же лучше? 

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

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

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

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

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

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

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

Что же касается меня, то я пишу комментарии (в основном на уровнях Javadoc и JSDoc) и требую этого от команд, работающих под моим руководством. 

Читайте также:

Читайте нас в Telegram, VK и Яндекс.Дзен


Перевод статьи Raj Nagappan: To Comment Code, or Not to Comment Code, That Is the Question

Предыдущая статьяАсинхронный Rust: проблемы и способы их решения
Следующая статьяКак добиться от моделей глубокого обучения большей генерализации?