Использование коментариев в исходном коде.
От: mrTwister Россия  
Дата: 05.12.10 12:09
Оценка: 33 (10) +10
Здравствуйте, коллеги.

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

Коментарии в коде могут решать разные задачи. В частности коментарии могут повышать читаемость кода. Но зачем повышать читаемость кода с помощью коментариев, если сам код можно структурировать таким образом, чтобы он читался легко, как книга? Для ответа на этот вопрос давайте определимся, для чего нам нужна читаемость. Итак, читаемость нам нужна, чтобы было легко понять:
1) Какую задачу решает код.
2) Каким образом код решает поставленную задачу.
3) Для чего потребовалось решать поставленную задачу. То есть почему этот код необходим.

Самый простой и понятный в этом списке — это пункт "2". Действительно, приложив определенные усилия и использовав специальные общеизвестные приемы, можно добиться того, что способ решения поставленной задачи станет очевидным из самого кода. В этом случае коментарии, описывающие способ решения задачи станут излишними, так как они будут дублировать информацию, которая и так уже содержится в коде. Don't repeat yourself (c)

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

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

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

Разрабатываются параллельно два проекта, основанные на общей кодовой базе. Оба проекта подлежат локализации на целую группу языков. В ходе разработки достаточно регулярно происходят ситуации, когда часть кода переходит из проектно-специфичной кодовой базы в общую кодовую базу и обратно. Тоже самое касается и ресурсов, используемых переезжаемым кодом — они также вместе с ним переезжают. Для того, чтобы облегчить перенос ресурсов, код не должен ничего знать об источнике этих ресурсов. Ресурсы из общей кодовой базы и проектной кодовой базы должны получаться из одного места. Для этого был введен следующий интерфейс (упрощенно):
public interface IResourceProvider
{
    string GetResource(string resourceIdentifier);
}

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

Также бывает, что комнтарии весьма уместны в случаях, когда выразительных способностей используемого языка программирования не хватает, чтобы явно в коде описать намерения программиста. Например, коментариями можно уточнить контракт некоторого интерфейса. Пример: в .NET есть интерфейс "IDisposable", с единственным методом "Dispose", осуществляющим очистку ресурсов. Контракт этого интерфейса предполагает, что метод "Dispose" может быть вызван любое количество раз и это не должно приводить к ошибкам, например к повторному освобождению уже освобожденных ресурсов. Подобный факт не может быть выражен непосредственно самим кодом, по-этому единственный способ — это документация (или коментарии, как частный случай документации). Можно мне возразить: а как же ассерты и юнит-тесты, ведь с их помощью тоже можно специфицировать контракт! Можно, но не контракт интерфейса, а контракт конкретной его реализации.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
лэт ми спик фром май харт
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.