Классы именования - Как не называть все «Менеджером <WhatEver>»? [закрыто]

1190

Давным-давно я прочитал статью (я полагаю, запись в блоге), которая поставила меня на «правильный путь» в отношении именования объектов: будьте очень скрупулезны в отношении именования объектов в вашей программе.

Например, если бы мое приложение (как типичное бизнес-приложение) обрабатывало пользователей, компании и адреса, у меня были бы классы a User, a Companyи Addressdomain - и, возможно, где-то всплыли бы a UserManager, a CompanyManagerи an AddressManager, которые обрабатывают эти вещи.

Так что вы можете сказать, что эти UserManager, CompanyManagerи AddressManagerделать? Нет, потому что Менеджер - это очень очень общий термин, который подходит для всего, что вы можете делать с объектами вашего домена.

В статье, которую я прочитал, рекомендуется использовать очень конкретные имена. Если бы это было приложение C ++, а UserManagerзадачей было выделение и освобождение пользователей из кучи, оно не управляло бы пользователями, а охраняло их рождение и смерть. Хм, может быть , мы могли бы назвать это UserShepherd.

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

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

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

В конечном счете, я хотел бы иметь что-то вроде каталога шаблонов (часто шаблоны проектирования легко предоставляют имена объектов, например, фабрику )

  • Factory - создает другие объекты (наименования взяты из шаблона проектирования)
  • Пастух - Пастух управляет временем жизни объектов, их созданием и отключением.
  • Синхронизатор - копирует данные между двумя или более объектами (или иерархиями объектов)
  • Няня - Помогает объектам достигать «пригодного для использования» состояния после создания - например, путем подключения к другим объектам

  • и т. д.

Итак, как вы решаете эту проблему? У вас есть постоянный словарный запас, вы придумываете новые имена на лету или считаете, что называть вещи не так важно или неправильно?

PS: меня также интересуют ссылки на статьи и блоги, обсуждающие эту проблему. Для начала вот оригинальная статья, которая заставила меня задуматься об этом: именование классов Java без «менеджера»


Обновление: резюме ответов

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

  • Старайтесь не создавать новые метафоры (няня)
  • Посмотрите, что делают другие фреймворки

Другие статьи / книги на эту тему:

И текущий список префиксов / суффиксов имен, которые я собрал (субъективно!) Из ответов:

  • координатор
  • строитель
  • писатель
  • читатель
  • укротитель
  • Контейнер
  • протокол
  • цель
  • конвертер
  • контроллер
  • Посмотреть
  • завод
  • сущность
  • ведро

И хороший совет для дороги:

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

froh42
источник
11
Он принадлежит в сообществе вики, потому что нет ни одного «лучшего» ответа. Это обсуждение.
DOK
13
Это противоречит интуиции. Разве они не должны называть это форумом? Я думаю, что вики предназначена для сбора фактов, а не мнений.
AaronLS
78
Спасибо за то, что держите это в курсе, но последний совет - ужасный совет! Если вы не можете придумать хорошее имя за 10 минут, возможно, что-то не так с вашим классом. (Со стандартными предостережениями: 1) совершенный - враг хорошего, 2) доставка - это особенность - просто помните, что у вас есть технический долг.)
Джефф Стерн
11
Если вы не можете придумать доброе имя за 10 минут, обратитесь к коллеге за помощью. Не сдавайся.
9
Если вы не можете придумать хорошее имя за 10 минут, попробуйте объяснить его своим коллегам; они могут подумать о хорошем имени (user338195), но попытка объяснить его, вероятно, поможет вам понять, что с ним не так ( Джефф ).
WillC

Ответы:

206

Я задал похожий вопрос , но, где это возможно, я пытаюсь скопировать имена уже в .NET Framework, и я ищу идеи в Java и Android Framework.

Похоже Helper,Manager и Utilэто неизбежные существительные, которые вы присоединяете для координации классов, которые не содержат состояния и, как правило, являются процедурными и статическими. АльтернативаCoordinator .

Вы можете получить особенно фиолетовый prosey с именами и идти на такие вещи , как Minder, Overseer, Supervisor, Administratorи Master, но , как я сказал , что я предпочитаю держать его , как вы привыкли к рамочным имен.


Некоторые другие общие суффиксы (если это правильный термин), которые вы также найдете в .NET Framework:

  • Builder
  • Writer
  • Reader
  • Handler
  • Container
Chris S
источник
4
Мне это очень нравится. Они не попадают в ловушку плохих или неизвестных метафор, потому что они уже используются .NET Framework. Возможно, было бы интересно взглянуть на другие библиотеки (Java), чтобы узнать больше о том, что обычно используется.
froh42
Я хотел бы предложить Conductor, как дирижер музыкального оркестра. Это, безусловно, важная роль, в зависимости от характера коллабораций, которые вам необходимо «вести» (другие объекты являются очень специализированными действующими лицами, которые должны реагировать на централизованное управление и не слишком беспокоиться о каждом другом соавторе).
heltonbiker
1
Я не верю, что решение -er классов состоит в том, чтобы придумать другое имя. Как я читал во многих других постах и ​​пытаюсь узнать ответ, вам нужно изменить архитектуру, а не только название.
Михаил Озерянский
116

Вы можете взглянуть на source-code-wordle.de , я проанализировал там наиболее часто используемые суффиксы имен классов .NET Framework и некоторых других библиотек.

Лучшие 20 являются:

  • атрибут
  • тип
  • помощник
  • коллекция
  • конвертер
  • обработчик
  • Информация
  • поставщик
  • исключение
  • служба
  • элемент
  • управляющий делами
  • узел
  • вариант
  • завод
  • контекст
  • вещь
  • дизайнер
  • база
  • редактор
Маркус Мейер
источник
147
В одной конкретной компании давно я знал инженера, настолько сытого по горло абсурдным и растущим множеством суффиксных правил, преследующих компанию, что он демонстративно заканчивал каждый урок Thingy.
8
Этот список имен сам по себе не так полезен без контекста, к которому следует применять суффикс.
Фред
65

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

Почему? Потому что метафоры зависят от культуры, а часто и от человека. Для вас название класса «няня» может быть очень ясным, но, возможно, это не так ясно для кого-то другого. Мы не должны полагаться на это, если только вы не пишете код, предназначенный только для личного использования.

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

CesarGon
источник
10
Этот аргумент действительно разрушается тем, что, очевидно, сама Фабрика является метафорой. Часто метафоры действительно проясняют, в чем может быть хорош объект, тогда как расплывчатость или универсальность автоматически гарантируют, что единственный способ выяснить, что делает код, это прочитать его полностью! Худший вариант развития событий.
Kzqai
1
+1 за избегание «милых» имен. Я думаю, это здорово быть настолько прямым с языком, насколько это возможно. (Конечно, не всегда легко быть прямым, лаконичным, точным и однозначным одновременно…)
andrewf
1
Изобретательный выбор глагола + «эр», как правило, будет более понятным для конкретных классов, чем яркая аналогия. С другой стороны, новые абстракции - вещи, которые представляют собой новую концепцию, новую «вещь», а не просто новую «вещь» - часто работают хорошо как метафоры («бобы» Java, «линзы» Haskell, GUI) "окна", "обещания" многих языков). Однако, большинство кодовых баз не будет иметь никаких настоящих изобретений.
Малнормалуло
51

Мы могли бы обойтись без какого - либо xxxFactory, xxxManagerили xxxRepositoryклассов , если мы смоделировали реальный мир правильно:

Universe.Instance.Galaxies["Milky Way"].SolarSystems["Sol"]
        .Planets["Earth"].Inhabitants.OfType<Human>().WorkingFor["Initech, USA"]
        .OfType<User>().CreateNew("John Doe");

;-)

оборота герцмейстер
источник
11
Как бы вы попали в параллельные вселенные и альтернативные измерения?
2010 года
23
Это просто: Omniverse.Instance.Dimensions ["Наши"]. Вселенные ["Наши"]. Галактики ... ... хорошо, хорошо, я признаю, что для этого потребуется перекомпиляция. ;-)
Герцмейстер
73
Обновление: это было добавлено в .NET 4.0:; Universe.Instance.ToParallel())
Connell
2
Хотя нарушает закон Деметры!
Джонас Г.
13
Это объекты и члены, а не имена классов
Гарри Берри
39

Это звучит как скользкий уклон к тому, что будет опубликовано на thedailywtf.com, "ManagerOfPeopleWhoHaveMortgages" и т. Д.

Я полагаю, это правильно, что один монолитный класс Manager не очень хороший дизайн, но использование 'Manager' не плохо. Вместо UserManager мы можем разбить его на UserAccountManager, UserProfileManager, UserSecurityManager и т. Д.

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

Мистер Бой
источник
8
А как насчет UserAccounter, UserProfiler и UserSecurer? Если вы избавляетесь от менеджера, вы вынуждены придумать конкретное определение, которое я считаю хорошим.
Дидье А.
10
А как насчет UserAccount, UserProfile, UserSecurity oO?
Клим
3
Я бы назвал это "MortageOwnersManager"
volter9
Иногда домен имеет конкретные имена. Как "MortageHolder", который может быть лучше, чем "MortageOwner"
borjab
24

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

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

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

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

Джефф Стерн
источник
1
Мне очень нравится идея использовать Policyсуффикс для классов, содержащих бизнес-логику
jtate
+1 за упоминание запаха кода, связанного с такими именами, как «Менеджер» и «Помощник». Я считаю, что если у меня нет четких названий вещей, это обычно происходит, по крайней мере частично, из-за некоторой неопределенности в моем понимании предметной области, будь то бизнес или техническая. Почти эквивалентно, это может означать, что я просто реактивно расстаюсь с классами, потому что они «стали слишком большими», что для меня также является признаком неадекватного моделирования. Это должен быть самый популярный ответ.
nclark
10

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

Брайан Агнью
источник
Фаулер - хороший пример для меня, но GOF - отличная рекомендация.
Лазарь
Прости мое невежество. На какую книгу Фаулера вы ссылаетесь?
Брайан Агнью
19
Хм, иногда это работает (например, как Фабрика или Стратегия), но в других случаях я чувствую, что это действительно передает способ реализации (я использовал образец!) Больше, чем намерение и работа класса. Например, самая важная вещь Синглтона - это то, что он представляет, а не то, что это Синглтон. Строгое именование по используемым шаблонам похоже на строгое именование по используемым типам. Например, венгерская нотация как неправильно примененная группой систем Windows (описывающая тип данных C вместо «тип намерения»)
froh42
1
Для классов технической инфраструктуры обычно желательно сделать реализацию прозрачной, и большинство имен канонических шаблонов проектирования сообщают как реализацию, так и намерение. Классы предметной модели - другое дело.
Джефф Стерн
10

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

Джаспер ван ден Бош
источник
8

Я думаю, что самая важная вещь, которую нужно иметь в виду, это: достаточно ли название описательно? Можете ли вы сказать по названию, что должен делать класс? Использование таких слов, как «Менеджер», «Сервис» или «Обработчик» в именах классов, может считаться слишком общим, но поскольку многие программисты используют их, это также помогает понять, для чего предназначен класс.

Я сам часто использовал фасадный рисунок (по крайней мере, я так думаю). Я мог бы иметьUser класс, который описывает только одного пользователя, и Usersкласс, который отслеживает мою «коллекцию пользователей». Я не называю класс a, UserManagerпотому что мне не нравятся менеджеры в реальной жизни, и я не хочу напоминать о них :) Простое использование формы множественного числа помогает мне понять, что делает класс.

Droozle
источник
Мне также очень нравится этот подход, потому что он упрощает идею управления объектами сверху вниз. Группа пользователей, скорее всего, подразумевает, что работа выполняется между пользователями, а не из UserManager вниз. Кроме того, наличие у пользователя ссылки на пользователей не так странно, как владение UserManager. Это больше открыто для относительного мышления, чем строго ООП.
Сеф Рид
Проблема с этим подходом состоит в том, что становится действительно трудно искать ваш код Users, особенно если вы передаете объект менеджера. this.users = new Users()Но тогда неизменно где-то еще в вашем коде usersбудет ссылаться на массив Users.
Снеговик
Как вы говорите, пользователи действительно подразумевают «совокупность пользователей» - совокупность сущностей с состоянием. Но SRP будет означать, что вы не захотите связывать управление пользователями (функциональность и бизнес-логику) с пользовательскими данными (состоянием). Не говоря, что вы не правы, просто UserManager подходит, если класс отвечает за управление пользователями, а не только за сохранение их состояния и базового CRUD.
Ричард Мур
5

Специально для C # я обнаружил, что в «Руководстве по проектированию инфраструктуры: условные обозначения , идиомы и шаблоны для многократно используемых библиотек .NET» содержится много полезной информации о логике именования.

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

AaronLS
источник
3

Я считаю, что самое важное здесь - это быть непротиворечивым в сфере видимости вашего кода, т. Е. До тех пор, пока каждый, кому нужно посмотреть / поработать над вашим кодом, понимает ваше соглашение об именах, тогда это будет хорошо, даже если вы решите вызвать их. «CompanyThingamabob» и «UserDoohickey». Первая остановка, если вы работаете в компании, это посмотреть, существует ли в компании соглашение об именовании. Если нет или вы не работаете в компании, создайте свои собственные термины, которые имеют смысл для вас, раздайте их нескольким доверенным коллегам / друзьям, которые хотя бы небрежно пишут код, и включите любые отзывы, которые имеют смысл.

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

Лазарь
источник
1
Тем не менее, последовательное, хотя и немного неинтуитивное соглашение лучше, чем просто запуск собственного соглашения. Люди, работающие над проектом, очень быстро выучат любое непротиворечивое соглашение и скоро забудут, что функциональность не совсем такая, какой можно ожидать с первого взгляда.
Мистер Бой
@ Джон, это именно то, что я сказал. Соглашение должно быть принято группой, и если вы работаете в компании, посмотрите, существует ли соглашение компании. Для компании я думаю о любой группе, будь то проектная команда с открытым исходным кодом или свободная коллекция программистов. Если бы все просто взяли то, что было доступно, что почти соответствовало бы их требованиям, то я думаю, что нам бы не хватало инноваций.
Лазарь
2

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

Например, UserRecordsClerk может быть лучше объяснено как расширение универсального интерфейса RecordsClerk, на котором и UserRecordsClerk, и CompanyRecordsClerk реализуют, а затем специализируются, то есть можно посмотреть на методы в интерфейсе, чтобы увидеть, для чего его / подклассы обычно / для чего вообще нужны.

Обратитесь к книге, такой как « Шаблоны проектирования», для получения дополнительной информации. Это отличная книга, которая может помочь вам разобраться в том, где вы хотите быть со своим кодом - если вы его еще не используете! ; о)

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

Каролина
источник
Я прокомментировал это в ответе Брайана Агнью. Я не чувствую, что имена шаблонов дают хорошие имена классов только в некоторых случаях (Factory, Strategy), но не в других (Singleton). Я хочу, чтобы имена отражали работу класса, а не то, как я это реализовал.
froh42