Рекомендуемый способ предотвращения именования загрязнения классами-помощниками на С#?

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

Я хотел бы сохранить имена структур thoses как можно более чистыми. Поэтому, когда у меня есть класс, который называется CarFinder, который сильно использует какой-то специальный объект Key, который используется (или главным образом) внутри, я бы хотел назвать этот объект Key вместо CarFinderKey.

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

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

В идеальном мире мне хотелось бы иметь ключевое слово как internal to this namespace, но поскольку этого не существует, это оставляет мне следующие варианты, о которых я могу думать:


  • Используйте internal и поместите класс в другой проект.

Преимущество: Идеальная инкапсуляция.

Недостаток: Много организационных издержек и ненужных сложных зависимостей.

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


  1. Поместите его в другое дочернее пространство имен, например CarFinding.Internal

Преимущество: Легко реализовать.

Недостаток: Все еще может загрязняться, когда пространство имен случайно импортируется.


  1. Поместите класс-помощник как дочерний класс в CarFinder.

Преимущество Не загрязняет внутренне и даже может рекламироваться как общедоступная вспомогательная структура, которая подвергается внешнему миру с помощью CarFinder.Key

Недостаток. Поместите класс-помощник в один файл или инкапсулируйте его во внешний файл с помощью public partial class вокруг него. Первый делает файл ненужным долго, второй просто чувствует себя очень уродливо.


  1. В любом случае назовите его CarFinderKey

Преимущество Легко реализовать.

Недостаток Добавляет, по моему мнению, слишком много пуха к CarFinder. Все еще не загрязняет имена, просто с именем, которое вряд ли столкнется.


Какое рекомендуемое руководство?

Ответ 1

Это мнение основано. Во всяком случае, я бы:

  • попробуйте сделать его приватным вложенным классом CarFinder, который обычно терпит неудачу, потому что Key необходимо передать в CarManager, вы знаете, что я имею в виду. Публичные вложенные классы обескуражены.

  • Я бы поставил его в пространство под-имен, называемое Core, общее имя для внутреннего содержимого. Для меня Core - это "пространство имен внутреннее" по соглашению об именах.

  • Чем больше проект, тем длиннее вам нужно. CarFinderKey по-прежнему является допустимым вариантом.

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

Ответ 2

Лично я не возражаю против дополнительного "пута", вызванного CarFinderKey, и вот почему: как-то работал над очень крупным проектом, где мы пытались использовать пространства имен для устранения неоднозначности имен.

Так как вы расширяете свою систему, вы можете легко получить 10 вкладок, открытых в редакторе кода, все с именем "Key.cs". Это было серьезно не весело.

Ответ 3

У меня была одна и та же дилемма много раз и лично использовала (3) и вариант (4).

(3): У меня нет проблем с тем, чтобы не вставлять вложенный класс/структуру в один и тот же файл (если он небольшой и действительно связан с родительским классом), а также не использовать отдельный файл в объявлении partial ParentClass - единственный Недостатком является то, что он получает еще один уровень отступов, но я могу жить с этим. У меня также нет проблем с нарушением правил FxCop или других рекомендаций - в конце концов, это просто рекомендации, а не обязательные. Но у многих людей есть проблемы со всеми или некоторыми из них, поэтому давайте двигаться дальше.

(4): Вы уже описали минусы. Я собираюсь поделиться тем, как я их преодолеваю. Опять же, это личное, и одно может или не понравится, но вот оно.

Во-первых, скажем, мы используем отдельный файл для класса ключей и называем класс CarFinderKey.

Затем внутри файл кода для класса CarFinder, мы поместим следующую строку в конце (или где-нибудь внутри) секции using:

using Key = CarFinderKey;

Таким образом, только внутри файла кода класса CarFinder, где-либо CarFinderKey требуется, мы можем просто ссылаться на него просто как Key, какова была цель. В то же время мы сохраняем все преимущества и не сталкиваемся. Intellisence работает без какой-либо проблемы. В VS2015 лампочка даже предложит "упростить имя" для вас везде, где она найдет CarFinderKey внутри этого файла.

Ответ 4

Ваше решение должно зависеть от вашего дизайна. Является ли ваш класс Key ключевым фактором только для CarFinders, или он также может использоваться для поиска мотоциклов или домов или что-то еще.

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

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

Если это так, и ваш дизайн диктует, что ключ полезен только для CarFinders или, может быть, даже: если он сконструирован таким образом, что он даже не полезен вне CarFinders, класс Key должен быть частью класса CarFinders, Сравните это с простым целым числом, которое вы использовали бы в классе CarFinders, вы бы объявили его закрытым в классе CarFinders, не так ли?

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

Ответ 5

Я бы поставил класс и их "помощники" в свое собственное пространство имен MyNamespace.CarFinding,

чтобы у вас было:

  • MyNamespace.CarFinding.CarFinder

  • MyNamespace.CarFinding.Key

и я просто поставлю это пространство имен в подпапку проекта.

Это не будет блокировать внутренний класс-помощник, который будет использоваться в другом месте проекта, но из родительского пространства имен вы можете ссылаться на своего помощника как на CarFinding.Key