Наилучшая практика для подклассификации имен

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

Например: Общий "DoiGraphNode" "DoiGraphNode", представляющий ресурс "DoiGraphNode", представляющий ресурс Java "DoiGraphNode" с соответствующим путем и т.д. И т.д.

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


Вариант 1. Всегда начинайте с названия концепции.

Таким образом: DoiGraphNode, DoiGraphNodeResource, DoiGraphNodeJavaResource, DoiGraphNodeWithPath и т.д.

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

Con: Не очень естественно? Все выглядит одинаково?


Вариант 2. Поместите специальный материал в начале.

Таким образом: DoiGraphNode, ResourceDoiGraphNode, JavaResourceDoiGraphNode, PathBaseDoiGraphNode, и т.д. и т.д.

Pro: Это очень ясно, когда я вижу его в коде

Con: Найти это может быть сложно, особенно если я не помню имя, отсутствие визуальной согласованности


Вариант 3: Поместите специальные материалы и удалите часть избыточного текста

Таким образом: DoiGraphNode, ResourceNode, JavaResourceNode, GraphNodeWithPath

Pro: Не так много писать и читать Con: Похоже, cr * p, очень непоследовательный, может конфликтовать с другими именами

Ответ 1

Назовите их тем, чем они являются.

Если присвоение им имени сложно или неоднозначно, это часто признак того, что класс делает слишком много (принцип единой ответственности).

Чтобы избежать конфликтов имен, выберите соответствующие пространства имен.

Вообще, я бы использовал 3

Ответ 2

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

Для чего это стоит, я обычно использую опцию 3, и из моего опыта, глядя на код другого человека, вариант 2, вероятно, более распространен, чем вариант 1.

Ответ 3

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

Лично я предпочитаю вариант 2. Как правило,.NET Framework называет свои объекты. Например, посмотрите классы атрибутов. Все они заканчиваются атрибутом (TestMethodAttribute). То же самое касается EventHandlers: OnClickEventHandler - рекомендуемое имя для обработчика событий, который обрабатывает событие Click.

Я обычно стараюсь следовать этому при разработке собственного кода и интерфейсов. Таким образом, IUnitWriter создает StringUnitWriter и DataTableUnitWriter. Таким образом, я всегда знаю, что их базовый класс, и он читает более естественно. Самодокументирующий код является конечной целью для всех гибких разработчиков, поэтому мне кажется, что он работает хорошо!

Ответ 4

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

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

Я часто использую параметр 3, когда подкласс обеспечивает существенное расширение или спецификацию, или если имена будут довольно длинными. Например, мои имена имен файловой системы производны от String но они значительно расширяют класс String и имеют значительно отличающиеся использование/значение:

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

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

  • Текст (интерфейс)
  • Text_abstract (абстрактный (базовый) класс обобщения)
  • Text_ASCII (конкретный класс для кодирования ASCII)
  • Text_unicode (конкретный класс, специфичный для кодировки в Юникоде)

Мне нравится, что интерфейс и абстрактный базовый класс автоматически появляются сначала в отсортированном списке.

Ответ 5

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

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