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

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

Это когда-нибудь случалось с вами? Разве это не случалось со всеми нами в какой-то момент нашей карьеры? Как не допустить повторения этой ошибки снова и снова?

Чистый код — вот ответ.

«Чистый код — это просто и понятно. Чистый код читается как хорошо написанная проза. Чистый код никогда не скрывает замысел дизайнера, а скорее полон четких абстракций и прямых линий управления». — Роберт С. Мартин

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

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

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

Принципы чистого кода

Существует множество различных принципов и методов написания чистого кода, поэтому я поделюсь теми, которые, по моему мнению, НЕОБХОДИМО включить в ваш код. Тем не менее, есть так много всего, что нужно узнать, поэтому я призываю вас продолжать обогащать свои знания по этому вопросу.

Давайте посмотрим на следующую строку кода:

Не знаю, как вы, а я думаю, что делает эта функция?

Итак, интуитивно я ищу файл, содержащий функцию getItems, и нахожу это:

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

Попробуем разбить эту функцию:

  1. Есть список для сопоставления и список элементов
  2. Отсортировать список товаров с ценами в порядке возрастания
  3. Отфильтруйте тот же список по цене, где цена ниже порогового значения.
  4. Создайте объект с идентификатором, сопоставленным с этими товарами, цена которых ниже порогового значения.

Хорошо — не страшно — здесь есть некоторая информация, но у меня все еще есть некоторые вопросы. Что такое items? Какой список мы отображаем? Что означает threshold ? И так далее…

Можем ли мы сделать лучше?

Имена переменных и функций

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

Вот наш пример:

Вот как мы могли бы улучшить его:

Что мы изменили здесь?

  1. Никаких магических чисел — мы удалили магическое число «100», которое не имело значения до того, как мы добавили его в переменную. Теперь, прочитав код, я понял, что у меня есть ученики с недельным бюджетом в 100, что, как я интуитивно понимаю, представляет некоторую валюту.
  2. Описательное имя функции — просто изменив имя функции, я теперь понимаю, что получаю продукты, которые не соответствуют бюджету, который в данном случае является недельным бюджетом учащегося (все продукты по цене менее 100).
  3. Осмысленное имя переменной — я понимаю из имени переменной affordableGroceries вместе с теми знаниями, которые я уже приобрел, что я получаю список продуктов, которые студент может себе позволить.

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

Функции

Основываясь на предыдущем примере, представьте, что вы только что получили задание обновить эту функцию, чтобы отфильтровать элементы, содержащие алкоголь grocery.alcohol === true, для учащихся, у которых age < 21.

Ради примера, скажем, я решил обновить функцию как есть, и теперь у меня есть это:

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

Функции должны делать только одну вещь, и эта вещь должна быть описана в имени функции. Это приведет к меньшим функциям с описательными именами, которые можно понять, даже не читая тело функции.

После разделения функции на функции одиночного действия мы получаем следующий результат:

Теперь, когда каждая функция выполняет только одно действие, обновление кода станет намного проще. Если мы хотим затем добавить еще одно условие к элементу бакалейной лавки (например, только бакалейные товары с действительной датой истечения срока годности), мы можем быстро увидеть по имени функции, что нам нужно обновить только isGroceryAvailableForStudent. Остальной код останется прежним.

Комментарии

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

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

Бум! Размышляя об этом, если вы автор и код, который вы пишете, является вашей историей, не будут ли комментарии просто мешать? Конечно, это повлияет на ход истории и сделает ее — поймите — сложнее для читателя, чтобы понять, что на самом деле происходит. Есть, конечно, крайние случаи, когда комментарий абсолютно необходим, но, как правило, их следует по возможности избегать.

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

Дублирующийся код

Ознакомьтесь с СУХИМ принципом написания кода — не повторяйтесь! Это очень важный принцип, когда дело доходит до написания чистого кода.

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

Вместо этого у вас должна быть одна функция, содержащая логику, которая используется в нескольких местах. Таким образом, если вам нужно внести изменение, вам нужно будет исправить его только в одном месте, и оно будет применяться ко всем.

Что дальше

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