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

StackOverflow https://stackoverflow.com/questions/574269

  •  05-09-2019
  •  | 
  •  

Вопрос

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

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

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


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

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

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

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


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

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

Профессиональный:Это очень ясно, когда я вижу это в коде

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


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

Таким образом:DoiGraphNode, ResourceNode, JavaResourceNode, GraphNodeWithPath Доиграйте, ResourceNode, JavaResourceNode, GraphNodeWithPath

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

Это было полезно?

Решение

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

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

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

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

Другие советы

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top