Есть ли хорошие методы или тесты для именования типов?

23

Неловкий, открытый вопрос, но я всегда сталкиваюсь с этой проблемой:

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

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

Это ухудшается (для меня), когда я пытаюсь назвать семейства типов, с базовым типом или интерфейсом, который описывает, что должны делать компоненты, а не как они работают. Это естественным образом приводит к тому, что каждый производный тип пытается описать вкус реализации (например, IDataConnectionи SqlConnectionв .NET Framework), но как вы выражаете что-то сложное, например, «работает по рефлексии и ищет определенный набор атрибутов»?

Затем, когда вы наконец выбрали название для типа, который, по вашему мнению, описывает то, что он пытается сделать, ваш коллега спрашивает: «WTF это DomainSecurityMetadataProviderдействительно делает? »

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

Существуют ли какие-либо простые тесты, которые я могу применить к имени, чтобы лучше понять, является ли оно «хорошим» и должно ли оно быть более интуитивным для других?

Пол Тернер
источник
20
есть шесть техник , которые доказали свою эффективность для меня: 1) потратить много времени на придумывание имен 2) использовать проверки кода 3) не стесняйтесь переименовывать 4) потратить много времени на придумывание имен 5) использовать проверки кода 6) не стесняйтесь переименовать
комнат
5
@gnat: Пожалуйста, оставьте свой ответ как ответ, чтобы мы могли проголосовать за него.
С.Лотт
3
Я часто использую тезаурус, когда делаю новые разработки, чтобы помочь мне придумать хорошие имена.
Ученик доктора Вили
3
Я стараюсь не называть что-либо "Менеджер". Алан Грин и Джефф Этвуд утверждают, что этот термин чрезмерно употребляется и слишком расплывчат, чтобы передать смысл. Я должен согласиться.
Ученик доктора Вилли

Ответы:

41

Для именования было доказано, что у меня есть шесть методов :

  1. тратить много времени на придумывание имен
  2. используйте код отзывы
  3. не стесняйтесь переименовывать
  4. тратить много времени на придумывание имен
  5. используйте код отзывы
  6. не стесняйтесь переименовывать

PS. В случае, если ваш API будет общедоступным, выше применяется до этого - потому что, вы знаете,

«Публичные API, как и бриллианты, вечны. У вас есть один шанс сделать это правильно, поэтому старайтесь изо всех сил ...» (Джошуа Блох, « Как создать хороший API и почему это важно» )

комар
источник
1
В случае, если это публичный API, вы можете использовать три дополнительных метода ...
UncleZeiv
1
@UncleZeiv: например ....?
FrustratedWithFormsDesigner
3
@FrustratedWithFormsDesigner: 1. потратить много времени на придумывание имен 2. использовать обзоры кода и 3. не стесняйтесь переименовывать
S.Lott
3
Этот ответ убедил меня, что, как правило, нет: нет простого способа получить правильные имена. Только стараться действительно тяжело работает.
Пол Тернер
4
7. Не стесняйтесь перепроектировать типы или функции, если окажется, что невозможно придумать для них подходящее имя. Хорошо продуманный код всегда можно правильно назвать.
Джорен
8

Мой базовый тест, если вы можете описать функцию переменной, используя только слова из переменной:

например, если DomainSecurityMetadataProvider либо «Предоставляет метаданные безопасности домена», либо «Предоставляет метаданные, относящиеся к безопасности домена», это хорошо.

Однако есть нюансы, которые варьируются от человека к человеку:

Например, для меня original_team_code - это код исходной команды, а для кого-то еще это может быть исходный код команды. Моим личным любимым из них был «UnsafeLegacyMutex», который я не мог не прочитать, но «Это устаревший мьютекс, который небезопасен», а не «Это мьютекс для устаревшего кода ThreadUnsafe».

Поэтому мой расширенный тест - записать переменную в доску / вики / чат, и пусть люди угадают, что это значит.

deworde
источник
7

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

На самом деле, нет.

Один совет, однако, состоит в том, чтобы избежать «пассивного голоса».

«DomainSecurityMetadataProvider» является пассивным. Там нет глагола, это все существительные и существительные, используемые в качестве прилагательных.

«ProvideMetadataForDomainSecurity» активнее. Там есть глагол.

Объектно-ориентированное программирование - это все (действительно) существительное-глагол. Существительное == объект. Глагол == метод. Так что имя класса, как правило, очень «существительное». Отказаться от этой привычки и начать вставлять глаголы сложно.

Существуют ли какие-либо простые тесты, которые я могу применить к имени, чтобы лучше понять, является ли оно «хорошим» и должно ли оно быть более интуитивным для других?

Да. Вы определили отличный тест в своем вопросе. Спроси других людей.

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

С. Лотт
источник
12
Не уверен, что согласен с идеей пассивного голоса. Для меня, классы имеют больше смысла, как существительные.
deworde
7
Вообще говоря, я пытаюсь держать имена своих типов в пассивном голосе, так как это соответствует стилю существительного глагола ООП. Я бы посчитал ProvideMetadataForDomainSecurityэто плохим именем типа. Имена методов обычно гораздо проще назвать именно потому, что я могу свободно использовать глаголы. Ограничение языка - суть проблемы.
Пол Тернер
Столько, сколько мне нравится «спрашивать людей» как настоящий тест, я должен спрашивать своих коллег о наименовании по крайней мере два раза в день. Я надеюсь на то, что не требует времени других людей.
Пол Тернер
2
Классы делать имеет смысл в качестве существительных. Проблема состоит в том, что эти сложные классы содержат длинные прилагательные с существительными. Предлоги тоже могут помочь.
С.Лотт
2
Сотрудничество - это секрет хорошего программного обеспечения. Сотрудничество требует времени. Там нет королевской дороги к хорошему письму.
S.Lott
6

Использование тезауруса

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

Классы, которые в основном содержат логику работы

Я склонен называть классы, которые в первую очередь предоставляют методы операций в структуре существительных-глаголов, таких как «EntityProvider», «EntityLocator» и т. Д.

Эти классы обычно не содержат много состояний.

Классы, которые содержат состояние

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

Примеры: Person, Employee, CurrentEmployee, FormerEmployee

Утилиты

Классы, которые содержат только статические методы, обычно рассматриваются как «служебные» классы, поэтому я последовательно называю их суффиксом «Utility».

Примеры: NetworkUtilities, FileUtilities

тесты

У меня нет хороших тестов для определения того, имеет ли что-то плохое имя, но я бы посоветовал попытаться использовать в имени единственное существительное и / или один глагол, а затем подумать, точно ли это существительное / глагол описывает то, что вы переименование.

Если вы чувствуете, что в классе / методе есть еще что-то, что не охвачено именем, то этот класс / метод может нуждаться в рефакторинге.

Алан Грин и Джефф Этвуд написали о пороках именования классов с суффиксом «Менеджер». Они утверждают, что термин «менеджер» чрезмерно употребляется и слишком расплывчат, чтобы передать что-либо значимое. Я должен согласиться.

В статье Джеффа также содержится список рекомендуемых руководящих принципов из «Полного кода» Стива Макконнела.

переменные

Недавно я экспериментировал с более длинными описательными именами переменных / параметров, которые включают предлоги, такие как «Of», «By», «For» и т. Д. Некоторые примеры показаны ниже:

string firstNameOfEmployee;

string lastNameOfEmployee;

// here I nimbly avoid worrying about whether to call it "Id" or "ID" :)
int idOfEmployee;

decimal amountForDeposit;

Account accountForDeposit;

Я считаю, что это прекрасно работает с функцией intellisense в Visual Studio, облегчающей ввод этих длинных имен. Я также обнаружил, что существует меньшее дублирование префиксов имен переменных (например, personID, personFirstName, personLastName против idOfPerson, firstNameOfPerson, lastNameOfPerson), обеспечивая лучший «хэш», который делает intellisense еще более полезным.

Ученик доктора Вилли
источник
1
Я остановлюсь на вопросе о длинных именах переменных, опять же, Visual Studio (если вы его используете) делает это не просто. Гораздо менее вредно иметь длинные имена переменных, которые являются явными, чем короткие имена переменных, когда нужно «подумать» или исследовать, что на самом деле означает это имя. Также подумайте о контексте. Я предпочел бы видеть "peopleToDelete", чем "listOfPeople". Опять же, Visual Studio сообщает вам тип переменной, нет необходимости включать ее.
Джон Бубриски
Мне также не нравятся сложные венгерские обозначения, которые вы добавили к именам переменных. Мне не нужно заботиться о том, является ли коллекция идентификаторов людей Listмассивом IEnumerableили ConcurrentQueue. Это куча идентификаторов, которые мне нужно перечислить, и детали реализации того, как они хранятся, являются ненужным умственным багажом. Хотя я в целом согласен с тем, что если более длинное имя значительно более наглядно, оно должно быть предпочтительнее более короткого и менее понятного имени.
Аллон Гуралнек
@Allon - Забавно, я собирался пересмотреть свой ответ на основе комментария SkippyFire. Я на самом деле согласен с вами; мой пример попахивает венгерской нотацией. Моя единственная защита состоит в том, что легко читать код и понимать типы данных без доступной IDE, например, если я читаю через diff-контроль исходного кода. Это не оправдание, хотя. :) Я собираюсь пересмотреть мой пример в соответствии с правилами firstNameOfEmployee, lastNameOfEmployee и т. Д.
Ученик доктора Уили
2

Затем, когда вы, наконец, выбрали имя для типа, который, по вашему мнению, описывает то, что он пытается сделать, ваш коллега спрашивает: «WTF действительно делает этот DomainSecurityMetadataProvider?»

Какое имя вы ожидаете для сложного и предметно-ориентированного класса? Это почти так же хорошо, как и то, что можно сделать, не называя имя вашего класса предложением (что заставит всех думать, что вы дали слишком большую ответственность одному классу)

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

Брайан
источник
Метаданные, о которых идет речь, не являются результатом рефлексии (но они описывают, как обрабатывать типы). Тип реализует ISecurityMetadataProviderинтерфейс, в котором существует точка инъекции в инфраструктуре безопасности, для предоставления информации подсистеме. Называть сложно.
Пол Тернер
Я считаю DomainSecurityMetadataProviderпровайдером DomainSecurityMetadataобъекта, где DomainSecurityMetadataнаходятся сами метаданные. Четкое и понятное имя. Мне даже не нужно знать, что это DomainSecurityMetadataтакое! Это просто какой-то объект, который предоставляет этот провайдер. Простое удаление Providerсуффикса не улучшает читабельность, а наоборот - уменьшает его. Без этого суффикса я бы подумал, что это просто метаданные (объект-контейнер для некоторых метаданных), но не объект для получения метаданных (поставщик).
Руслан Стельмаченко
0

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

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

nimcap
источник
-1

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

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

deworde
источник
1
Вы должны удалить этот ответ и отредактировать в своем
исходном
Я думаю, что это другой ответ на мой другой ответ.
deworde
-1

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

kizzx2
источник