Чистый код. Тезисы. Часть 2.

Комментарии #

Не комментируйте код — перепишите его.
Брайан У.Керниган и П. Дж. Плауэр

  • Не стоит относиться к комментариям как к абсолютному добру.

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

  • Грамотное применение комментариев должно компенсировать нашу неудачу в выражении своих мыслей в коде.

  • Если вы оказались в ситуации, в которой необходимо написать комментарий — хорошенько подумайте, нельзя ли пойти по другому пути и выразить свои намерения в коде.

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

  • Истину можно найти только в одном месте: в коде. Только код может правдиво сообщить, что он делает.

  • Одной из распространенных причин для написания комментариев является низкое качество кода. Не тратьте время на написание комментариев, объясняющих зозданную вами путанницу. Лучше исправьте свой код!

  • Объясните свои намерения в коде.

    if (employee.isEligibleForFullBenefits())

    лучше чем

    // Проверить, положена ли работнику премия
    if ((employee.flags && HOURLY_FLAH) && employee.age > 65)
  • Иногда бывает полезно включить комментарий с пояснениями к коду. Пример такого комментария — пояснение к регулярному выражению.

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

    public int compareTo(Object o)
    {
    		if(o instanceof WikiPagePath()
    		{
    				WikiPagePath p = (WikiPagePath) 0;
    				String compressedName = StringUtil.join(names, ");
    				String compressedArgumentName = StringUtil.join(p.names, "");
    				return compressedName.compareTo(compressedArgumentName);
    		}
    		return 1; // Больше, потому что относится к правильному типу
    }
  • Иногда смысл загадочного аргумента или возвращаемого значения удобно преобразовать в удобочитаемую форму. В общем случае лучше подумать, как сделать так, чтобы этот аргумент или возвращаемое значение говорили сами за себя; но если они являются частью стандартной библиотеки или используются в коде, который Вы не можете изменить, то пояснительный комментарий может быть весьма полезным.

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

  • Иногда бывает полезно оставить заметки «на будущее» в форме комментариев // TODO. Такие комментарии напоминают о том, что сделать необходимо, но невозможно сделать прямо сейчас.

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

  • Не пишите комментарии «на скорую руку». Если уж вы решаете написать комментарий, не жалейте времени и напишите лучший из всех возможных комментариев.

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

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

  • Не используйте HTML в комментариях. Он затрудняет чтение комментария в редакторе/IDE. За уркашение комментариев соответствующим кодом HTML должен отвечать инструмент, а не программист.

  • Короткие функции не нуждаются в долгих описаниях.

Форматирование #

  • Мы хотим, чтобы читатель, заглянувший в код программы был поражен нашей аккуратностью, логичностью, вниманием к мелочам и стройностью кода. Мы хотим, чтобы наша работа выглядела профессионально. Если вместо этого читатель видит беспорядочную массу кода, он решит, что такое неуважение к мелочам проникло и в другие аспекты проекта.
  • Маленькие файлы обычно более понятны, чем большие.
  • Файл исходного кода должен выглядеть как газетная статья. Имя файла должно быть простым, но содержательным. Одного имени должно быть достаточно, чтобы читатель понял, открыл он нужный модуль или нет.
  • Каждая строка представляет выражение или условие, а каждая группа строк представляет законченную мысль. Эти мысли следует отделять друг от друга пустыми строками. Каждая пустая строка становится зрительной подсказкой, указывающей на начало новой самостоятельной концепции.
  • Если пустые строки разделяют концепции, то вертикальное сжатие подчеркивает тесные связи Поэтому строки кода, между которыми существует тесная связь, должны быть «сжаты» по вертикали.
  • Концепции, тесно связанные друг с другом, должны находиться поблизости друг от друга по вертикали. Не заставляйте читателя прыгать туда-сюда по исходным файлам и классам.
  • Переменные следует объявлять как можно ближе к месту использования.
  • Переменные экземпляров должны объявляться в начале класса. Это не увеличивает вертикальное расстояние между переменными, потому что в хорошо спроектированном классе они используются многими членами класса.
  • Если одна функция вызывает другую, то эти функции должны располагаться вблизи друг от друга по вертикали. Вызывающая функция должна находиться над вызываемой (если это возможно).
  • Некоторые фрагменты кода требуют, чтобы их разместили вблизи от других фрагментов. Такие фрагменты обладают определенным концептуальным родством. Чем сильнее родство, тем меньше должно быть вертикальное расстояние между ними. Примеры такого родства:
    • одна функция вызывает другую;
    • группа функций выполняет аналогичные операции;
    • функции/переменные используют единую схему выбора имен и выполняют разные варианты одной операции.
  • Как и в газетных статьях, читатель ожидает, что самые важные концепции будут изложены сначала, причем с минимальным количеством второстепенных деталей. Низкоуровневые подробности естесственно приводить в последнюю очередь. Это позволяет нам бегло просматривать файлы, извлекая суть из нескольких начальных функций, без погружения в подробности.
  • По возможности строки должны быть короткими. Автор установил себе «верхнюю планку» в 120 символов.
  • Горизонтальные пропуски используются для группировки взаимосвязанных элементов и разделения разнородных элементов. Именно поэтому имена функций не отделяются от открывающих скобок. Это обсуловлено тем, что имя функции тесно связано с ее аргументами.
  • У каждого программиста есть свои любимые правила форматирования, но если он работает в группе, то должен руководствоваться групповыми правилами.
  • Код программного продукта должен быть оформлен в едином стиле.
  • Хорошая программная система состоит из набора удобочитаемых документов, оформленных в едином, согласованном стиле. Читатель должен быть уверен в том, что форматные атрибуты, встречающиеся в одном исходном файле, будут иметь точно такой же смысл в других файлах.