Совершенный код: злые однострочники

Программисты любят компактный код. Если он реализован грамотно, то такой код легко читается и не содержит частей, которые заставляют думать о нем больше, чем нужно.
Например:
Для знакомых с концепцией фильтрации он предельно понятен и достаточно хорош, чтобы не тратить время на его дальнейшую шлифовку.
Но иногда желание сделать код компактным приводит к обратному эффекту. Падает его читаемость и усложняется рефакторинг. Причем автор кода не всегда осознает это. Пока программист находится в контексте задачи, почти любое решение, каким бы плохим оно ни было, кажется ему понятным. Программист в это время держит все детали в голове, и ему легко рассуждать об этом коде. Чего не скажешь о тех, кому предстоит его читать. Более того, даже сам автор кода уже через день, два, неделю, с трудом сможет разобраться в нем.
Подписывайтесь на канал Кирилла Мокевнина в Telegram — чтобы узнать больше о программировании и профессиональном пути разработчика
Проекты Хекслета – неиссякаемый источник примеров кода для данной статьи. Я выбрал несколько наиболее интересных и ниже проведу их разбор.
Этот пример все еще понятен и не содержит сложной логики, но уже сложен для восприятия. Почему? Из-за большого количества вложенных вычислений. Вызов функции – это сложно. Чем больше вызовов, тем сложнее их соединять между собой в голове. Проблема усугубляется тем, что не всегда очевидно чем является результат вызова. Поэтому приходится в голове держать сразу все части выражения.
Самый простой способ сделать код понятным, как это ни странно, создавать переменные (или константы) с говорящими названиями (исходим из того, что функции уже названы хорошо). Тогда наш код превратится в такой:
Теперь о коде рассуждать проще, потому что большая задача превратилась в несколько маленьких. Стало понятнее, с чем мы имеем дело (это конфиги!). Как бонус, упрощается отладка, так как можно посмотреть, что лежит в промежуточных переменных. Можно ли его улучшить дальше? Да, вложенные вызовы всегда должны вызывать желание избавиться от них. Особенно если вложенные вызовы производят побочные эффекты.
Для себя я вывел правило, которое называю “правило трех вызовов”. Оно говорит о том, что нужно разбивать выражения, содержащие три и более вложенных вызова:
Хозяйке на заметку. Лучший способ избавиться от вложенных вызовов – воспользоваться механизмом pipeline. Благодаря babel он есть и в js.
Другой пример:
Это выражение уже сложнее и требует умственных усилий для анализа. Особенно вторая часть, там где toBe
. Именно здесь притаились три вызова и вдобавок интерполяция.
Отрефакторим этот код:
Да, кода стало 4 строчки вместо одной, но это тот случай, когда больше означает лучше. Этот код не добавляет новой логики и не увеличивает сложность. Он делает код самодокументируемым.
Следующий пример:
Выражение на грани фола. Его можно прочитать, но второе условие в предикате слишком сложное. Оставляю вам это на самостоятельную работу. Покажите в комментариях пример того, как бы вы разделили этот код.
Ну и последний пример:
Попробуйте понять в нем, что во что вложено и что из чего вызывается.
Содержание
Дополнительные материалы:
Kirill Mokevnin
6 лет назад