Читаемый код: 10 практик успешного написания

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

Читаемый код: 10 практик успешного написания

Известно, что хороший код чаще читается, чем пишется. С одной стороны, читаемый код или нет – дело субъективное. С другой стороны, правила оформления текстов программ зависят от языка, компании, ранее написанной программной базы.

1. Форматируйте программный код

Возьмём для начала предложение на естественном языке, например, английском:

i love programming the games are cool its fun to play them don't you think

Прочитать его будет проще, если мы разделим текст на смысловые части – предложения и словосочетания:

I love programming! The games are cool. It's fun to play them – don't you think?

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

Разбиение программного кода

Аналогичные инструменты необходимы и для представления текстов, написанных на различных языках программирования. Но в случае программирования появляются менее очевидные вопросы.

Рассмотрим код на JavaScript:

fill(80,204,55);rect(100,0,200,400);
var draw=function(){var numCircles = 6;for (var i=numCircles; i>1; i--){var radius=i*7;
if(mouseX>100&&mouseX<300) {fill(255,255,255);}else{fill(80,204,55);}
ellipse(mouseX,mouseY,radius,radius);}};

Несмотря на неряшливость, код при запуске работает корректно. Для выполнения интерпретатором нет никакой разницы, как именно оформлен текст. Достаточно выполнения формальных требований.

А вот человек с таким кодом вряд ли захочет работать. Нужно его изменить. Что в первую очередь вам захочется сделать?

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

fill(80,204,55);
rect(100,0,200,400);

var draw=function(){
var numCircles=6;
for (var i=numCircles; i>1;i--) {
var radius=i*7;
if (mouseX>100 && mouseX<300) {
fill(255,255,255);
} else {
fill(80,204,55);
}
ellipse(mouseX,mouseY,radius,radius);
}
};

Можно видеть, что для этого достаточно сделать перенос строки после одного из трёх символов (одной из фигурных скобок или точки с запятой). Но и такое представление программного кода не вполне удобно для чтения.

Более читаемый код: отступы

Так же, как мы выделяем абзацы отступами, полезно выделять и конструкции языка программирования:

fill(80,204,55);
rect(100,0,200,400);

var draw=function(){
    var numCircles=6;
    for (var i=numCircles; i>1;i--) {
        var radius=i*7;
        if (mouseX>100 && mouseX<300) {
            fill(255,255,255);
        } else {
            fill(80,204,55);
        }
        ellipse(mouseX,mouseY,radius,radius);
    }
};

Большинство сред разработки автоматически определяют стиль отступов или позволяют настроить его в соответствии с внутренними правилами компании. А в некоторых языках (например, Python) отступы даже являются частью языка.

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

Пробелы

Ещё одним важным типом отступов являются пробелы. Пробелы позволяют быстрее визуально выделять взаимодействующие в конструкциях отдельные объекты. Обычно пробелы ставятся после запятой и точки с запятой.

А еще пробелами ограничиваются операторы, например, операторы присваивания и сравнения.

fill(80, 204, 55);
rect(100, 0, 200, 400);

var draw = function() {
    var numCircles = 6;
    for (var i = numCircles; i > 1; i--) {
        var radius = i * 7;
        if (mouseX > 100 && mouseX < 300) {
            fill(255, 255, 255);
        } else {
            fill(80, 204, 55);
        }
        ellipse(mouseX, mouseY, radius, radius);
    }
};

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

2. Вычищайте мёртвый код

Мёртвый код – это закомментированные блоки программы, неиспользуемые переменные, неиспользуемые функции и т. д. Они сами как будто говорят: "Мне нет дела до этого кода". Это выглядит так, будто ваш код начал гнить. Ситуация похожа на классическую теорию разбитых окон. Такой код нужно искать и избавляться от него в первую очередь.

3. Не злоупотребляйте вложениями

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

4. Используйте объекты ООП вместо надстроек над другими объектами

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

5. Не пишите слишком большие блоки кода

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

6. Не пренебрегайте именованием объектов

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

7. Сделайте код таким, чтобы комментарии не были нужны

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

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

8. Пусть функции возвращают разумные значения

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

9. Используйте правило трёх

Пусть нам сообщили, что сейчас будет названа последовательный ряд чисел. Назвали число 2 и спросили: «Какое число следующее?». Конечно, вы не можете знать. Если известно, что следующее число 4, уже можно строить какие-то предположения. Если же за четвёркой идёт 16, мы убеждаемся, что это квадратичный ряд. То есть вы с большой уверенностью можете предположить из трёх предыдущих чисел, что следующее за ними число – 256. Только три итерации позволяют определить характер последовательности. Поэтому правило называется правилом трёх.

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

10. Читаемый код – это симметрия

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

Источники

Какие-то из принципов, возможно, показались тривиальными. Другие, напротив, могли удивить.

Делитесь вашими соображениями в комментариях.

МЕРОПРИЯТИЯ

Комментарии

ВАКАНСИИ

Добавить вакансию
Golang разработчик (middle)
от 230000 RUB до 300000 RUB
Продуктовый аналитик в поддержку
по итогам собеседования

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ