🔍

7 советов как сделать свой код чище

🗓️ 16 декабря 2020 г.🥤 8 мин. чтения

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

1. Удалите ненужные комментарии в коде

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

function mergeArrays(...arrays) {
  return arrays.reduce((acc, arr) => [...acc, ...arr], [])
}

Добавление JSDoc в этот код не улучшит читаемость. Я ожидаю, что члены моей команды знают, что такое spread оператор. А если нет, то могут спросить об этом во время code review.

2. Сфокусируйтесь на нейминге

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

Представьте себе функцию, которая объединяет 2 массива чисел и генерирует новый уникальный список чисел. Как бы вы это назвали? Что-то вроде этого?

function mergeNumberListIntoUniqueList(listOne, listTwo) {
  return [...new Set([...listOne, ...listTwo])]
}

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

Давайте её разделим на 2 отдельные функции — это сделает их название намного проще и в то же время более удобным для повторного использования.

function mergeLists(listOne, listTwo) {
  return [...listOne, ...listTwo]
}

function createUniqueList(list) {
  return [...new Set(list)]
}

Конечно проще создать однострочную функцию, не вызывая новых функций, но иногда однострочные функции не так читаемы.

3. Упрощайте условия if

Не усложняйте условия с оператором if. Я часто вижу вот такое:

if (value === 'duck' || value === 'dog' || value === 'cat') {
  // ...
}

но можно сделать этот код читабельнее:

const list = ['duck', 'dog', 'cat'];

if (list.includes(value)) {
  // ...
}

Таким образом вы создаете читаемый фрагмент кода, который выглядит как предложение на английском языке.

Если список включают значение, тогда...

4. Ранний выход

Также данный принцип называют "Ранний возврат", но мне ближе название «Ранний выход».

Прежде чем рассказать о чём идёт речь, я хотел бы показать вот такой кусок кода:

function handleEvent(event) {
  if (event) {
    const target = event.target;

    if (target) {
      // ...
    }
  }
}

Я думаю, что вы видели что-то подобное раньше. Здесь мы пытаемся проверить, не является ли event ложным и доступно ли свойство target. Проблема в том, что мы уже используем два оператора if и такая вложенность усложняет чтение кода.

Посмотрим, как здесь можно сделать «ранний выход»:

function handleEvent(event) {
  if (!event || !event.target) {
    return;
  }
  
  // ...
}

Применяя здесь «ранний выход», вы проверяете, не являются ли event и event.target ложными. Сразу видно, что мы уверены, что event.target не является ложным значением.

Также ясно, что никакой другой код не выполняется, если это утверждение ложно.

5. Деструктурирующее присваивание

В JavaScript мы можем деструктурировать объекты или массивы. Давайте посмотрим на код ниже:

// Destructuring an object
const numbers = {one: 1, two: 2};
const {one, two} = numbers;

console.log(one); // 1
console.log(two); // 2

// Destructuring an array
const numbers = [1, 2, 3, 4, 5];
const [one, two] = numbers;

console.log(one); // 1
console.log(two); // 2

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

Прекрасный пример — выборка данных из API и получение объекта ответа, у которого есть свойство данных.

const url = "http://localhost:8080/api/v1/organizers/1"
const response = await axios.get(url)

const {name} = response.data

Этот пример кода показывает, что вы загружаете организатора с идентификатором 1. У объекта организатора есть свойство name, и вы извлекаете его.

В этом нет ничего плохого. Этот код работает и в порядке.

Но почему name до сих пор name? Будет ли это единственным свойством name во всей области видимости? И от какого объекта это свойство name?

Избегайте этих вопросов, переименовав свойство.

const url = "http://localhost:8080/api/v1/organizers/1"
const response = await axios.get(url)

const {name: organizerName} = response.data

Этот код становится более читабельным. Все будут знать, что переменная — это имя организатора.

6. Оставьте код лучше, чем вы его нашли

Вы обнаружили код с душком? Исправьте это! Вы нашли неиспользуемую переменную? Удалите её!

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

Но каждое воскресенье вы должны убирать всю квартиру, а это занимает более 4 часов. Вам бы это понравилось?

Я уверен, что ответ отрицательный.

Так что, если все сразу уберут небольшие части квартиры, то в воскресенье работы будет меньше.

То же самое и с кодовой базой. Если в кодовой базе часто остаётся код с душком, никто не удаляет неиспользуемые переменные и линтер сходит с ума и выдает около 77 предупреждений, то в один прекрасный день кому-то придётся сесть и разобраться со всеми предупреждениями, потратив уйму времени на решение мелких проблем (Надеюсь, это будете не вы 🙂)

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

7. Code style

Последний, но не менее важный совет — определите стиль кода в своей команде.

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

Чтобы не держать это в голове, достаточно один раз настроить linter и/или prettier.

Есть так много инструментов, которые можно использовать для решения подобных проблем. У меня настроено в моей IDE применение prettier в момент сохранения файла.

Также можно настроить pre-commit хук с использованием Husky. У Prettier также есть страница в документации о pre-commit хуках.

Этот pre-commit хук всегда запускает настроенную команду перед каждым коммитом в git репозиторий. Настроив его правильно, то он будет запускать prettier и применит все правила ко всем файлам. Это гарантирует, что у команды всегда будет один и тот же стиль кода.

Заключение

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

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

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

Copyright © 2021