Кодирование с помощью Scapes

Почему самодокументирующийся код все еще нуждается в комментариях

И как эти комментарии помогают нам учиться

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

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

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

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

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

float velFinal(float v0, float a, float t) {
    return v0 + (a * t)
}

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

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

float computeFinalVelocity(float initialVelocity, float acceleration, float timeInSeconds) {
    return initialVelocity + (acceleration * timeInSeconds)
}

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

Я не просто так выделил слово «контекст». Это был до боли простой пример, но контекст и люди идут рука об руку, как спагетти и фрикадельки. Я очень люблю спагетти и фрикадельки.

Но что, если у вас совсем другая функция? Представьте, что в этом сценарии клиент использует неоднозначную терминологию в своей организации? Может быть, у них есть продукт под названием «Ускорение», который и близко не соответствует определению из физики. Вы могли бы/должны, конечно, назвать функцию как-нибудь понятным и добавить аналогичные изменения, которые мы сделали выше, чтобы сделать код самодокументируемым. Является ли этот метод ответом на все ситуации, которые могут возникнуть у клиента?

Представьте, что в аналогичном сценарии происходит следующее:

function computeSomethingImportant(ProductData productData){
    …
    subOptimalAlgorithm(productData)
    …
}

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

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

Что, если бы у вас был тот же самый пример, и вы изменили его на

function computeSomethingImportant(ProductData productData){
    …
    //TODO: suboptimal algorithm used due
    // to some constraint. Replace with much
    // better shimalamablam algorithm
    // ASAP to avoid total PM meltdown in September
    subOptimalAlgorithm(productData)
    …
}

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

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

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

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

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

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

Комментарии являются катализатором контекста, но что такое контекст и откуда мы знаем, что он способствует обучению и, следовательно, пониманию? Существуют рецензируемые исследовательские работы и книги, на которые ссылались сотни других исследователей, которые подтверждают это утверждение о том, что понимание условий окружающей среды способствует обучению. В одной из таких книг, Контекст и обучение под редакцией P Balsam, A Tomie (2014), которая была первоначально написана в 1985 году и снова опубликована в 2014 году издательством Psychology Press, в первой главе говорится об обучении и контексте:

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

Основное внимание в книге уделяется «специфическим особенностям поставленной задачи». Это означает, что исследования показали, что контекст, связанный с конкретной задачей, является ключом к облегчению процесса обучения.

Хорошо размещенные и хорошо написанные комментарии учат, в то время как разработчики находятся в процессе обучения.

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