Какой лучший подход к именованию классов?

92

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

Классам, реализующим конкретный шаблон проектирования, можно дать имя на основе хорошо известного имени шаблона (например, FooFactory, FooFacade), а классы, которые непосредственно моделируют концепции предметной области, могут брать свои имена из проблемной области, но как насчет других классов? Есть ли что-нибудь вроде тезауруса программиста, к которому я могу обратиться, когда мне не хватает вдохновения и я хочу избежать использования общих имен классов (например, FooHandler, FooProcessor, FooUtils и FooManager)?

Генри
источник
6
это отличный вопрос! Закрывать это ИМХО неоправданно, лучше бы программистам перенести сайт.
Тимофей
1
Я согласен, следует открыть или переместить
ftl
Я видел много этих замечательных вопросов, закрытых casperOne. Может быть, он мог бы работать в Википедии в качестве делециониста?
Perlator

Ответы:

59

Я процитирую несколько отрывков из « Паттернов реализации » Кента Бека:

Простое имя суперкласса

«[...] Имена должны быть короткими и яркими. Однако, чтобы сделать имена точными, иногда, кажется, требуется несколько слов. Выход из этой дилеммы - выбор сильной метафоры для вычисления. С метафорой в уме, даже отдельные слова несут с собой богатую сеть ассоциаций, связей и значений. Например, в среде рисования HotDraw мое первое имя объекта на рисунке было DrawingObject . Уорд Каннингем пришел вместе с метафорой типографики: рисунок похож на напечатанная, разложенная страница. Графические элементы на странице - это фигуры, поэтому класс стал Figure . В контексте метафоры Figure одновременно короче, богаче и точнее, чем DrawingObject ".

Квалифицированное имя подкласса

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

Дайте подклассам, которые служат корнями иерархий, свои простые имена. Например, в HotDraw есть класс Handle, который представляет операции редактирования фигуры, когда фигура выбрана. Он называется просто Handle, несмотря на расширение Figure . Существует целое семейство ручек, и у них наиболее подходящие названия, такие как StretchyHandle и TransparencyHandle . Поскольку Handle является корнем своей собственной иерархии, он заслуживает простого имени суперкласса больше, чем квалифицированного имени подкласса.

Еще одна проблема в именовании подклассов - это многоуровневые иерархии. [...] Вместо того, чтобы слепо добавлять модификаторы к непосредственному суперклассу, подумайте об имени с точки зрения читателя. На какой класс ему нужно знать этот класс? Используйте этот суперкласс как основу для имени подкласса ".

Интерфейс

Два стиля именования интерфейсов зависят от того, как вы думаете об интерфейсах. Интерфейсы как классы без реализации должны быть названы , как если бы они были классы ( Simple суперкласс , Квалифицированные Подкласс Имя ). Одна из проблем этого стиля именования состоит в том, что хорошие имена используются до того, как вы перейдете к именованию классов. Интерфейсу с именем File нужен класс реализации, называемый что-то вроде ActualFile , ConcreteFile или (фу!) FileImpl(и суффикс, и аббревиатура). В общем, важно сообщить, имеете ли вы дело с конкретным или абстрактным объектом, независимо от того, реализован ли абстрактный объект как интерфейс или как суперкласс, менее важно. Отсрочка различия между интерфейсами и суперклассами хорошо поддерживается этим стилем именования, позволяя вам изменить свое мнение позже, если это станет необходимым.

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

Для более подробного обсуждения покупайте книгу! Это стоит того! :)

Марсио Агиар
источник
1
«Иногда присвоение имен конкретным классам просто более важно для связи, чем сокрытие использования интерфейсов. В этом случае префикс имен интерфейсов с помощью« I ». Если интерфейс называется IFile, класс можно просто назвать File». Это так забавно, потому что в книге Роберта К. Мартина «Чистый код» я обнаружил, что мы предпочли бы называть реализации как FileImpl, а не называть интерфейс как IFile, потому что мы не хотим, чтобы клиент знал, что мы обслуживаем их интерфейс. И в книге ^ есть цитаты из книги, о которой вы говорите :)
Cristian Ciobotea
39

Всегда выбирайте MyClassA, MyClassB - это обеспечивает хорошую альфа-сортировку.

Я шучу!

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

Реальная проблема?

У меня слишком много уроков. Если вы попытаетесь придерживаться принципа единой ответственности , все станет намного лучше. Вместо одного монолитного класса PrintHandler вы можете разбить его на PageHandler , PageFormatter (и т. Д.), А затем создать мастер- класс Printer, который объединяет все вместе.

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

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

Удачи!

Роб Купер
источник
Согласитесь с тем, чтобы не указывать имена шаблонов в имени класса. Что, если шаблон изменится позже, когда изменится реализация?
thegreendroid
2
Я бы предпочел поместить в имя название шаблона. Зачем? Потому что, если мне нужно посмотреть на детали реализации (например, частный конструктор), чтобы узнать, что это синглтон, это замедляет меня как читателя, и в зависимости от моего уровня навыков я могу не понять, что это на самом деле часть класса общей картины. Синглтон и частный конструктор - сомнительный пример, но для более сложных шаблонов (посетитель, адаптер и т. Д.) Он становится довольно сложным. Если шаблон изменится, то причина в том, что этих классов больше не будет ...
dragan.stepanovic 01
28

В превосходной речи Джоша Блоха о хорошем дизайне API есть несколько хороших советов:

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

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

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

Если это хороший совет для общедоступного API, то для любого другого класса он не повредит.

Джош Сегалл
источник
1
ссылка на видео на youtube youtube.com/watch?v=aAb7hSCtvGw
Эндрю Гарри,
12

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

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

Саймон Джонсон
источник
9

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

Люк Холливелл
источник
3

Если ваш "FooProcessor" действительно обрабатывает foos, то не откажитесь дать ему такое имя только потому, что у вас уже есть BarProcessor, BazProcessor и т. Д. В случае сомнений, очевидное лучше. Другие разработчики, которым необходимо прочитать ваш код, могут не использовать тот же тезаурус, что и вы.

Тем не менее, для этого конкретного примера не повредит конкретизация. «Процесс» - довольно широкое слово. Например, действительно ли это «FooUpdateProcessor» (который может стать «FooUpdater»)? Вам не нужно слишком «изобретательно» подходить к именованию, но если вы написали код, вы, вероятно, имеете довольно хорошее представление о том, что он делает, а что нет.

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

McKenzieG1
источник