ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ. Я переношу свои письменные работы на Medium. Это пост, который я решил переопубликовать. Первоначально он был написан в 2014. Эти старые посты я оставил относительно без изменений. Некоторые (или большинство) конкретных деталей сейчас могут быть устаревшими, но я считаю, что основная идея этих статей перевешивает любую устаревшесть этих сообщений.

Разделы в Правилах именования переменных и классов Оттингера:

  • Используйте имена, раскрывающие намерения
  • Избегайте дезинформации
  • Делайте значимые различия
  • Используйте произносимые имена
  • Используйте доступные для поиска имена
  • Избегайте кодировок
  • Избегайте ментального картирования
  • Используйте фразы с существительными и глаголами
  • Не будь милым
  • Выберите одно слово для каждой концепции
  • Не каламбур
  • Используйте богатые источники имен
  • Сделайте контекст значимым

Именование — одна из тех вещей в программировании, которая всегда присутствует. Тим Оттингер написал Правила именования переменных и классов для Object Mentor в 1997 году. Эта статья до сих пор считается одной из основополагающих статей на тему именования и программирования. Я подумал, что было бы забавно прочитать его и добавить свои мысли.

Давайте начнем.

Оттингер начинает свою статью словами:

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

Этот акцент на «краткости» меня сразу же беспокоит. С автодополнением и IDE размер имени переменной или класса — это последнее, о чем я собираюсь беспокоиться. Но давайте посмотрим, к чему это приведет.

Используйте имена, раскрывающие намерения

Проблема не в простоте кода, а в неявности кода: степени, в которой контекст не является явным в самом коде.

К такому выводу пришел Оттингер, взглянув на относительно простой образец Python. Здесь Оттингер имеет в виду следующее: Даже самый простой код должен быть ясным по своему назначению.

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

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

Избегайте дезинформации

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

Некоторые слова означают разные вещи для разных людей. Оттингер использует слово «список» как пример чего-то, что может означать разные вещи для разных людей.

Он утверждает, что вместо AccountList можно использовать AccountGroup или даже BunchOfAccounts.

Кроме того, будьте осторожны, используя переменные или классы, имена которых длинные и лишь немного отличаются друг от друга. Например, XYZControllerForEfficientHandlingOfStrings и XYZControllerForEfficientStorageOfStrings.

Забавно, что Оттингер предупреждает нас об использовании строчных букв L и прописных букв o в наших именах, поскольку они могут быть легко неверно истолкованы как единицы и нули. Поднимите руку, если вы уже были укушены этим.

Делайте значимые различия

Если имена должны быть разными, они также должны означать что-то другое.

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

Оттингер предостерегает нас от добавления пустых слов и числовых рядов в наши имена только для того, чтобы удовлетворить требования компиляторов. Создание таких переменных, как string, string1, string2, ничего не добавляет к смыслу. То же самое можно сказать о добавлении шумовых слов, таких как Info или Data, для создания новых классов, таких как ProductInfo или ProductData.

Однако мне трудно понять «шумовые слова». Я вижу случаи, когда ProductInfo и ProductData могут быть полезны. Но я чувствую, что намерение Оттингера здесь состоит в том, чтобы предупредить использование этих слов, если нельзя использовать что-то более явное.

Кроме того, если вы создаете класс с именем ProductInfo, возможно, было бы лучше иметь метод info в классе Product. Тогда вы могли бы просто позвонить Product.info.

Используйте произносимые имена

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

Используйте доступные для поиска имена

Две выдающиеся цитаты из этого раздела:

… более длинные имена имеют преимущество перед более короткими именами, а любое доступное для поиска имя имеет преимущество перед константой в коде.

и

Я лично предпочитаю, чтобы однобуквенные имена можно было использовать ТОЛЬКО в качестве локальных переменных внутри коротких методов.

Мне нравятся эти четкие правила. Хотя меня беспокоит использование однобуквенных переменных в любом месте. У меня также есть некоторые проблемы с согласованием идеи о том, что «более длинные имена превосходят более короткие имена», но раньше мы видели, что мы должны быть «краткими» в наших именах.

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

Избегайте кодировок

Оттингер завершает этот раздел следующей цитатой:

Современным языкам не нужна кодировка типов.

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

Избегайте ментального картирования

Не заставляйте читателя вашего кода переводить значение переменной.

И насколько крута эта цитата?

Смарт переоценен. Ясность — король. Самые умные должны использовать свой талант для написания кода, который другие вряд ли поймут неправильно.

Используйте фразы с существительными и глаголами

Создайте переменные, которые позволят вам писать код, который читается как предложение.

Оттингер рекомендует, если это звучит неважно или трудно понять, вы должны увидеть, насколько сложно вам или вашим коллегам использовать API вашего класса или насколько сложно читать модульные тесты для вашего класса.

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

Таким образом, вместо Interest.new(30) у вас может быть что-то вроде Interest.thirty_year_mortgage.

Не будь милым

Однажды я назвал основную функцию класса parsenator. Не делайте этого.

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

Выберите одно слово для каждой концепции

Честно говоря, этот раздел был мне не совсем ясен. Из этого я вывожу идею о том, что вы должны выбрать имя, а затем придерживаться его. Будьте последовательны с вашим интерфейсом.

Хотя это может быть утомительно, люди, которые используют ваш API, будут вам благодарны.

Не каламбур

Не используйте одно и то же имя для разных идей.

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

Используйте разные названия для разных действий или вещей.

Используйте богатые источники имен

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

Однако на более высоком уровне используйте проблемные доменные имена. Использование названий проблемных или бизнес-доменов делает намерение ясным, когда вы взаимодействуете на этом уровне. Как легче понять Game.target.find(23) или Game.enemy_hit_in_quadant?(23)?

Сделайте контекст значимым

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

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

Во-вторых, не ставьте перед всеми вашими классами аббревиатуры проблемной области.

Если все ваши классы начинаются с BAZ, это не только ничего не добавляет к ясности ваших намерений, но и работает против автодополнения ваших редакторов и IDE.

Вывод

Работа Оттингера исключительна. Хотя мне нравилось писать этот анализ, я уверен, что упустил нюансы, которые там есть.

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

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

Первоначально опубликовано на сайте geopet.github.io 15 августа 2014 г.