Хорошие привычки программистов

Перевод статьи «How to Set Your Future Self Up for Success with Good Coding Habits».

Photo by Chase Chappell on Unsplash

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

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

Пересмотр сделанного

Это случалось со всеми нами. Вы возвращаетесь к части проекта, которой занимались шесть месяцев назад. Пытаетесь разобраться с багом и вдруг натыкаетесь на нечто ужасное. Вероятно, спрашиваете себя: «Да кто же мог написать такой код?!».

Чтобы выяснить, кто это тут такой «талантливый», вы обращаетесь к истории коммитов в git (при помощи команды git log -p имя_файла.js). И тут оказывается, что этот код — ваших рук дело!

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

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

Кроме того, порой нам не хватает понимания всей картины в целом. Работая над решением отдельной задачи, мы так погружаемся в процесс, что наше зрение становится как бы слишком сфокусированным. А чтобы охватить взглядом всю картину, нужно смотреть шире, и для этого следует отступить на шаг. Шестимесячный перерыв как раз и выступает в роли такого «отступления».

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

Улучшение читаемости кода

В чем проблема?

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

// Example ternary statement
const isFreezing = temperature <= 32 ? true : false;

Но иногда это отрицательно сказывается на читаемости кода. Да, кажется, что все выглядит красиво и очень чисто (еще бы, всего одна строка!). Но если выражение будет несколько сложнее, кому-то придется потратить довольно много времени, чтобы в нем разобраться.

const minutes = 30;
const cookie = {
  color: 'black'
};

const cookieStatus = minutes > 20 ? cookie.color === 'black' ? 'burned' : 'done' : 'not done';

Что делать?

Скорее всего, большинство из нас разберутся, каким будет cookieStatus в этом примере (спойлер: burned). Но подумайте о том, сколько времени у вас на это ушло. Даже если это всего одна или две секунды, это вынуждает вас совершать дополнительные умственные усилия.

А ведь можно написать и так:

const minutes = 30;
const cookie = {
  color: 'black'
};
let cookieStatus;

if ( minutes <= 20 ) {
  cookieStatus = 'not done';
} else if ( cookie.color === 'black' ) {
  cookieStatus = 'burned';
} else {
  cookieStatus = 'done';
}

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

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

И да, это же простой пример. А представьте реальный сценарий с важной бизнес-логикой, при котором вы можете попадать в такие ситуации довольно часто.

Скажем, вам нужно добавить еще одно условие. Тернарное выражение усложняется, его становится еще труднее дебажить или расширять. А вот if-предложения по-прежнему остаются легко читаемыми.

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

Photo by Chase Chappell on Unsplash

Единообразие кода

В чем проблема?

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

// Jim's code style

function MyComponent() {
  function handleOnClick() {
    alert('Click!')
  }
  return (
    <button onClick={handleOnClick}>My Button</button>
  )
}

// Creed's code style

const MyComponent = () => <button onClick={() => alert('Click!')}>My Button</button>;

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

И при этом каждый по-своему прав (ну, кроме тех, кто не хочет ставить точки с запятыми)! В спорных вопросах стиля существуют вполне резонные аргументы в пользу любого варианта. Но это отнюдь не означает, что каждый может писать, как хочет.

Что делать?

Единообразие кода очень важно для поддержания здоровья кодовой базы. Обычно цель ставится так: «Код должен быть таким, будто его писал один человек».

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

Ошибки, которые выдает линтер

Но чтобы достигнуть такого результата, совсем не обязательно прилагать титанические усилия. Есть много инструментов, позволяющих вылавливать несоответствия стиля, например, Eslint для JavaScript. Более того, некоторые инструменты могут даже сами исправлять найденные несоответствия (например, Prettier).

Комментирование кода

В чем проблема?

Комментирование кода это способ добавить контекст к сложной логике, а это важно.

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

Что делать?

Добавив добротный набор комментариев, вы поможете человеку, который придет вам на смену, лучше понять ваш код (что важно — понять еще до внесения каких-то изменений).

// DONT CHANGE - WILL STOP MAKING MONEY

const shouldMakeMoney = true;

function makeMoney() {
  if ( shouldMakeMoney ) {
    return noMoney;
  }
  return moreMoney;
}

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

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

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

Photo by Chase Chappell on Unsplash

Документирование решений

В чем проблема?

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

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

Что делать?

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

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

/**
 * DOCUMENTATION
 * Order Total >= 25: Discount %10
 * Order Total >= 50: Discount %15
 * Order Total >= 100: Discount %20
 * Order Total >= 75: Free Shipping
 */

const orderSubTotal = 84.00;
let orderTotal = orderSubTotal;

// If the order total is under 75, apply shipping discount

if ( orderTotal < 75 ) {
  orderTotal = addShipping(orderTotal);
}

// If the order total reaches a threshold, apply given discount

if ( orderTotal >= 100) {
  orderTotal = applyDiscount(orderTotal, .2);
} else if ( orderTotal >= 50 ) {
  orderTotal = applyDiscount(orderTotal, .15);
} else if ( orderTotal >= 25 ) {
  orderTotal = applyDiscount(orderTotal, .1);
}

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

Комментарии, в свою очередь, могут совершенно не касаться правил как таковых, но описывать эффективный и логичный способ их реализации. У нас должна оставаться возможность обновлять код в соответствии с измененными правилами бизнеса (например, снизить размер скидки со $100 до $80) и при этом не переделывать его.

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

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

Создание эффективных пул-реквестов

В чем проблема?

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

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

Что делать?

Создание пул-реквестов не должно быть искусством. Основная их цель — рассказать о вносимых изменениях. Как минимум, они должны отвечать на вопросы «что?» и «зачем?».

Для создания пул-реквестов можно пользоваться специальными инструментами (вроде шаблонов). Они помогут избежать однострочных описаний вроде «Закрывает [тикет]» или, что того хуже, — полного отсутствия описаний.

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

  • Что изменилось?
  • На что это влияет?
  • Как я могу воспроизвести или протестировать изменение?

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

Укрепление кода при помощи тестов

В чем проблема?

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

Не имея тестов, мы полагаемся на человеческий фактор. И не важно, насколько хорош ваш QA Engineer: что-нибудь все равно ускользнет от его внимания. Я не хочу сказать, что тесты помогут выявить абсолютно все баги. Но мы можем использовать некоторые доступные инструменты, чтобы предотвратить большую часть возможных проблем.

Что делать?

Если комментарии это способ рассказать, как именно что-то работает, тесты это способ проверить, работает ли оно вообще. Для этого нам нужны повторяемые тестовые случаи.

function applyDiscount(value, discount) {
  const discountAmount = value * discount;
  return value - discountAmount;
}

expect(applyDiscount(10, .1)).toEqual(.9);
expect(applyDiscount(532151235, .1054)).toEqual(476062494.831);

Если я напортачу с математикой в функции applyDiscount, высока вероятность, что этот код не пройдет тест (никогда не говори никогда).

Но тестирование не должно быть чем-то сложным. Есть много инструментов, способных нам помочь. Например, для запуска юнит-тестов можно использовать Jest. А можно поверх этого добавить еще и Enzyme — для тестирования React-компонентов. Вы также можете использовать Cypress для интеграционного тестирования. Этот инструмент будет кликать по всему вашему приложению, чтобы убедиться, что все компоненты хорошо взаимодействуют друг с другом.

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

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

Выводы

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

[customscript]techrocks_custom_after_post_html[/customscript]

[customscript]techrocks_custom_script[/customscript]

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Прокрутить вверх