Я создаю библиотеки с различными небольшими служебными функциями в C # и пытаюсь принять решение относительно именования пространств и классов. Моя текущая организация выглядит так:
Company
Company.TextUtils
public class TextUtils {...}
Company.MathsUtils
public class MathsUtils {...}
public class ArbitraryPrecisionNumber {...}
public class MathsNotation {...}
Company.SIUnits
public enum SISuffixes {...}
public class SIUnits {...}
Это хороший способ организовать пространство имен и классы, или есть лучший способ? В частности, кажется, что наличие одного и того же имени в пространстве имен и имени класса (например, Company.TextUtils
пространства имен и TextUtils
класса) является просто дублированием и предполагает, что схема могла бы быть лучше.
SISuffix
вместоSISuffixes
), и я думаю, что единственное число читается лучше.Suffix.A
читается как «суффикс А». Кроме того, я вообще избегаю повторения имен с уровня в иерархии. То есть вместо тогоCompany.SIUnits.SISuffixes
, чтобы я склонялсяCompany.SI.Suffix
иCompany.SI.Unit
Ответы:
Очень трудно определить, насколько эффективна ваша стратегия именования в отрыве от остального кода.
Пространство имен должно дать некоторое представление о том, где оно вписывается в широкую структуру вашей кодовой базы, а имя класса обычно описывает, какую функциональность или концепцию он представляет в этой области.
Не будем обращать внимания, в вашем конкретном примере, если у вас, вероятно, будет гораздо больше классов типа «Util», я бы подумал о их размещении
Company.Utils.Maths
и т. Д. Таким образом, если вам нужно добавить функциональность, которая является общей для нескольких служебных областей, вы уже естественное место для этого.источник
Есть хороший документ, который содержит множество правил, которым вы должны следовать, чтобы соответствовать Microsoft: Framework Design Guidelines .
Одна вещь, которую вы должны изменить: не называйте классы как их пространство имен. Это приведет к путанице компилятора. Просто не надо. Найдите лучшее имя для класса пространства имен.
источник
Прошло много времени с тех пор, как я работал с C # или экосистемой .NET, поэтому я не могу сказать, каковы текущие рекомендуемые рекомендации. Я бы порекомендовал изменить ваши имена, как это:
То, что я сделал здесь, это удалил «Utils» из имен пространства имен. Я думаю, что «Util» не должен быть в пространстве имен, потому что
Company.Text
пространство имен может однажды содержать классы, которые не являются текстовыми служебными классами. ПространствоCompany.Math
имен уже содержит то,ArbitraryPrecisionNumber
что не похоже на «утилиту».Удаление «Util» из пространства имен также устраняет любую путаницу, которая может возникнуть из-за наличия двух вещей с одинаковыми именами (как упоминалось в ответе Роберта: /software//a/340440/13156 )
Другой способ, которым вы могли бы организовать код:
В этом случае все служебные классы находятся в одном пространстве имен.
Company.Text
Пространства имен больше нет, поскольку единственное, что было, это служебный класс.Лично я считаю первый вариант более понятным.
источник
Использование одного и того же имени для пространства имен и класса внутри него проблематично.
Если пространство имен содержит более одного класса, почему другие классы будут помещены туда? это не кажется правильным, потому что цель имени пространства имен состоит в том, чтобы описать все классы в нем, а не только один. Например, если у вас есть
JsonSerialization
,BinarySerialization
иXmlSerialization
классы в пространстве имен, будет ли смысл называть пространство именXmlSerialization
?Обычно происходит то, что из-за извлечения класса из существующего пространства имен или слияния нескольких классов или другой реорганизации вы попадаете в пространство имен, содержащее основной класс; постепенно, второстепенные классы помещаются туда, потому что они немного связаны с исходным классом. Например, пространство имен
LogParser
может содержать один классLogParser
, а затем кто-то помещает егоLogConverter
, потому что оно весьма связано с анализатором, затемLogSearcher
и т. Д. Проблема здесь в том, что имя пространства имен не изменилось: как только оноLogConverter
было добавлено, имя должно быть измененоLogsProcessing
или простоLogs
.Если пространство имен содержит только один класс, это может быть признаком проблемы в организации кода.
Хотя я несколько раз видел ситуации, когда один класс с надлежащими принципами SOLID сильно отличался от всего остального в кодовой базе и поэтому был помещен в выделенное пространство имен, такие случаи редки. Чаще всего это свидетельствует о проблеме. Точно так же ничто не мешает вам иметь класс, содержащий один метод, но чаще всего такие классы указывают на проблему.
Даже если ваше пространство имен содержит только один класс, обычно есть способ быть более конкретным при именовании класса и более общим при именовании пространства имен. Представьте себе приложение, которое, помимо прочего, должно в данный момент преобразовывать файлы, записанные в формате ABC, в формат DEF. Преобразование не требует какой-либо десериализации / сериализации в / из бизнес-объектов и выполняется путем применения набора регулярных выражений, которые достаточно коротки, чтобы помещаться в сам класс преобразования, называемый
AbcToDefConverter
, Вся логика преобразования занимает около 80 LLOC примерно в десяти взаимозависимых методах - кажется, что в этой ситуации абсолютно нет необходимости ни делить существующий класс, ни создавать дополнительные классы. Поскольку остальная часть приложения не имеет ничего общего с преобразованиями, класс нельзя сгруппировать с другими классами в существующих пространствах имен. Таким образом, создается пространство именAbcToDefConverter
. Хотя в этом нет ничего неправильного, можно также использовать более общее имя, напримерConverters
. В таких языках, как Python, где более короткие имена предпочтительнее и повторяется, это может даже статьconverters.Abc_To_Def
.Поэтому для пространств имен используйте разные имена, чем для классов, которые они содержат. Имя класса должно указывать, что делает класс, а имя пространства имен должно выделять то, что является общим для всех классов, входящих в него.
Кстати, вспомогательные классы по своей природе ошибочны: вместо того, чтобы содержать что-то конкретное, например, арифметику произвольной точности, они скорее содержат все, что не нашло своего пути в других классах . Это просто плохое наименование, как
Miscellaneous
каталог на рабочем столе, что свидетельствует об отсутствии организации.Именование существует по причине: чтобы сделать вашу жизнь проще, когда вам нужно найти вещи позже. Вы знаете, что если вам нужно нарисовать график, вы можете попытаться найти «график» или «график». Когда вам нужно изменить способ, которым приложение генерирует счета, вы будете искать «invoic [e / ing]» или «bill». Точно так же попробуйте представить себе случай, когда вы скажете себе: «Хм, эта функция, вероятно, должна быть найдена в misc». Я не могу
Посмотрите на .NET Framework. Разве большинство этих классов не являются служебными классами? Я имею в виду, они имеют мало общего с бизнес-доменом. Если я работаю над финансовым приложением, или веб-сайтом электронной коммерции, или образовательной платформой следующего поколения, сериализация XML или чтение файлов, выполнение запросов SQL или выполнение транзакций - все это полезные вещи. Тем не менее, они не называются
UtilitySerialization
илиUtilityTransaction
, и они не находятся вUtility
пространстве имен. У них есть собственные имена, которые позволяют (и легко, спасибо разработчикам .NET!) Найти их, когда они мне нужны.То же самое касается ваших классов, которые вы обычно используете в своих приложениях. Они не являются служебными классами. Это классы, которые делают определенные вещи, и вещи, которые они делают, должны быть именами классов.
Представьте, что вы создали некоторый код, который имеет дело с единицами и преобразованием единиц. Вы можете назвать это
Utility
и быть ненавидимыми вашими коллегами; или вы можете назвать этоUnits
иUnitsConversion
.источник
Math
? Я не понимаю, как добавлениеUtility
суффикса ко всему облегчит нашу жизнь. При использованииSystem.Math.Min()
метода .NET вы бы предпочли писатьSystemUtility.MathUtility.Min()
? Во всех случаях я сильно отредактировал свой ответ, поэтому теперь он должен быть понятнее.