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

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

И напоследок перед тем, как я стал: на этот блог повлияла и вдохновила книга Роберта К. Мартина Чистый код: руководство по гибкому разработке программного обеспечения. Это обязательное чтение для любого разработчика.

Информация

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

Если код следует читать как книгу, тогда имена должны быть достаточно значимыми, чтобы передавать информацию. Предложение A man went to the place for something не передает ничего существенного. a went to b for c передает даже меньше. Сравните это с The King of France went to the gallows to die. Это передает смысл, рисует картину в нашем сознании и запоминается. Имена в коде должны делать то же самое.

Информативные имена раскрывают намерение

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

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

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

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

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

Информативные имена избегают дезинформации

Точно так же, как имена должны раскрывать намерение и способствовать контексту, они не должны также искажать намерение или контекст. Например, The King of France went to the gallows to sort of die. Фраза sort of немного отвлекает от этого предложения. Это заставляет нас усомниться в нашем первоначальном предположении, что его повесят, и не заменяет его ничем полезным. Точно так же дезинформация в коде принимает форму противоречия обычным предположениям, которые мы делаем.

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

Не используйте имена, которые сбивают с толку типы данных. Например, let bestDoctorArray = “Matt Smith”. Любая переменная с array в имени должна быть массивом.

Не нарушайте правила использования заглавных букв. Использование заглавных букв многое говорит о значении. В соответствии с соглашением вашего языка или кодовой базы: переменные обычно представляют собой camelCase или snake_case с первой строчной буквой, константы - CAPITALIZED, а классы - CamelCase с заглавной первой буквой каждого слова. Отклонение от этого оставит будущих разработчиков в недоумении относительно (1) цели объекта, (2) почему он был написан определенным образом, а другие были написаны иначе, и (3) каким образом они должны написать имя.

Информативные имена избегают шума

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

Наиболее распространенные способы создания шума - это внесение небольших изменений в написание имени (например, user, uzer, userr) и добавление цифр к буквам или переменным, чтобы показать, что они похожи, но все же разные (например, a1, a2, a3) . Хотя эти имена достаточно различимы для компилятора, их различия не несут ничего полезного для разработчика.

Возьмем, к примеру, название этой статьи. Если я назвал его The 3 I’s of Meaningful Names: i1, i2, and i3, я не передал ничего значимого, о чем еще не было сказано; более того, я не привел к полезному различию между ними (спасибо Мэтью Джардине за то, что он придумал это красивое название, которое я почти использовал).

Шум также возникает в виде избыточности, когда он не нужен. Например: let Car = {carMake: …, carColor: …};

Должно быть: let Car = {make: …, color: …};

Кроме того, добавление Info или Data в конец имен не добавляет никакой дополнительной информации, которой нет в их базовом слове. userInfo и user передают одно и то же значение; аналогично с productData и product.

Личность

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

Произносимый

Разработчик может лучше определить и сразу понять произносимое и написанное правильно имя. Большинство из нас достаточно прилично читают - особенно те, кто читает блоги, - что мы можем обрабатывать произносимые слова быстрее, чем слова, полные шума или сокращений. Многие люди, в том числе и я, произносят то, что мы читаем. Поэтому чтение getCoAddr(c) { return c.addr }; занимает у меня немного больше времени, чем getCompanyAddress(company) { return company.address };.

Отличительный

Избегайте слишком похожих имен. Тонкие различия слишком сложно различить с первого взгляда. Например, getAccountsForAllCurrentEmployees() и getAccountsForAllFormerEmployees(). В зависимости от того, где наш взгляд падает на слово, мы можем не заметить различия, особенно при синтаксическом анализе сотен строк кода.

Читая, мы часто смотрим на общую структуру, а не на детали слова. Рассмотрим старый мем: "Aoccdrnig to a rscheearch at Cmabrigde Uinervtisy, it deosn’t mttaer in waht oredr the ltteers in a wrod are, the olny iprmoetnt tihng is taht the frist and lsat ltteer be at the rghit pclae". Хотя здесь часто встречаются орфографические ошибки, мы все же можем прочитать и понять их значение. Это добавляет уверенности в том, что мы упускаем из виду детали. В качестве дополнительной поддержки моей точки зрения, что мы замалчиваем детали, вы, возможно, упустили тот факт, что каждый раз, когда я использовал слово «the» в этом разделе (вне кавычек), я использовал его дважды.

В заключение убедитесь, что различия достаточно различимы.

С возможностью поиска

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

 const getCoAddr = (c) => {
   switch (c.state) {
     case “TX”:
       console.log(c.addr);
       break;
     case “CA”:
       console.log(“Out of State”);
       break;
   };
 };

Если бы я попытался использовать команду find любого текстового редактора для аргумента c, мне вернули бы лишние результаты. Это становится еще более проблематичным, поскольку проект растет, и я ищу имена в файлах. Эта проблема не ограничивается однобуквенными именами. Он также распространяется на имена, которые не имеют достаточного значения, например user. Если имя user используется вообще, оно, скорее всего, будет использоваться на протяжении всего проекта. Поиск в проекте всех экземпляров user будет утомительным до такой степени, что функция поиска окажется бесполезной. Обратите внимание, что поиск по умолчанию для многих текстовых редакторов вернет все экземпляры user, даже если они являются частью более крупного слова, такого как current_user, new User или aMuseRecording.

Учреждение

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

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

Внутреннее учреждение

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

Выше я упомянул об одном стилистическом соглашении, а именно о том, как имена пишутся с заглавной буквы. Если консенсус в отношении констант состоит в том, что они пишутся заглавными буквами, то продолжайте делать это для констант. Если все имена файлов - snake_case, а имена основных функций файлов - camelCase, придерживайтесь этого соглашения. Обычно для этого есть веская причина. Даже если для этого нет веской причины, закономерность есть. А нарушение шаблона создает шум и дезорганизацию, особенно когда файлы расположены в алфавитном порядке.

Другое внутреннее соглашение - решить, какой глагол добавлять к именам функций (например, get, retrieve и fetch); или существительное, которое нужно добавить к именам переменных (например, nameArray, nameGroup или просто names). Неважно, какой глагол или существительное вы выберете, просто убедитесь, что они последовательно используются в базе кода.

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

Внешнее учреждение

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

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

Лучшее место для изучения языковых условностей - это обратиться к их руководству по стилю. Однако вот несколько универсальных стандартов:

  • Классы должны быть написаны с заглавной буквы CamelCase существительными или существительными-фразами, например, Users или UserAccounts.
  • Переменные должны быть в нижнем регистре camelCase или snake_case существительными или существительными-фразами - например, selectedUser или selected_user.
  • Функция и методы должны быть в нижнем регистре camelCase или snake_case, начинаться с глагола и заканчиваться существительным или существительной-фразой, например, getUsers или get_accounts.

Квалификатор области действия

Вышеупомянутые правила можно (но, возможно, не следует) изменить в некоторых незначительных обстоятельствах, прежде всего в зависимости от уровня области действия. Я думаю об этом как о обратном правиле области действия: чем шире область действия, тем более строго следует соблюдать правила; чем уже сфера применения, тем свободнее. Большинство из приведенных выше принципов следует придерживаться независимо от области применения, но есть небольшое пространство для маневра в отношении длины и детализации имен. Примечание. Это правило не является еще одним I для создания значимых имен; это просто квалификатор.

Однобуквенные имена

Поскольку однобуквенные имена не передают намерений автора, их следует избегать. Однако, когда их использование является частью более широкого соглашения языка, тогда это соглашение передает намерение. Например, JavaScript использует e как сокращение для события. Многие языки используют i для обозначения счетчика в for цикле или index в итеративной операции. Это значение теряется по мере продвижения от места объявления переменной. В результате их следует использовать только в узком объеме.

Неопределенно названные переменные

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

Доступные для поиска имена

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

Квалификатор абстракции

Принимая во внимание наше желание сохранить наш код DRY, допустимо использование более общих имен в абстракциях. Однако даже в очень абстрактной функции все равно есть имена намного лучше, чем obj или a1, a2, a3.

Вывод

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

Источники

  1. Роберт С. Мартин, Чистый код: руководство по гибкому разработке программного обеспечения
  2. чистый-код-javascript, https://github.com/ryanmcdermott/clean-code-javascript
  3. руководство по стилю рубина, https://github.com/bbatsov/ruby-style-guide