Лучшая практика для именования подклассов - PullRequest
11 голосов
/ 22 февраля 2009

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

Например: Универсальный "DoiGraphNode" DoiGraphNode, представляющий ресурс DoiGraphNode, представляющий ресурс Java «DoiGraphNode» со связанным путем и т. Д. И т. Д.

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


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

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

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

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


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

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

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

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


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

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

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

Ответы [ 5 ]

5 голосов
/ 22 февраля 2009

Назовите их такими, какие они есть.

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

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

Лично я бы использовал 3

5 голосов
/ 22 февраля 2009

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

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

2 голосов
/ 24 февраля 2009

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

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

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

1 голос
/ 01 марта 2009

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

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

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

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

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

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

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

0 голосов
/ 22 февраля 2009

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

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

...