31

I'm building libraries with various small utility functions in C#, and trying to decide on a namespace and class naming convention. My current organization is like this:

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 {...}

Is this a good way to organize the namespace and classes, or is there a better way? In particular it seems like having the same name in the namespace and class name (e.g. Company.TextUtils namespace and TextUtils class) is just duplication and suggests that the scheme could be better.

user
  • 525
  • 1
  • 5
  • 10
  • 11
    https://martinfowler.com/bliki/TwoHardThings.html – richzilla Jan 18 '17 at 15:09
  • 5
    The Microsoft guidelines recommend singular names for enums (so `SISuffix` instead of `SISuffixes`), and I think that singular reads better. `Suffix.A` _reads as_ "suffix A". Also, I generally avoid repeating names from a level up in the hierarchy. That is, instead of `Company.SIUnits.SISuffixes`, I'd lean towards `Company.SI.Suffix` and `Company.SI.Unit` – Harrison Paine Jan 18 '17 at 17:39
  • 2
    @richzilla http://thecodelesscode.com/case/220 – Tin Wizard Jan 18 '17 at 18:20
  • @HarrisonPaine enums with the `[Flags]` attribute should be named in plural as per FxCop rules. [CA1717: Only FlagsAttribute enums should have plural names](https://docs.microsoft.com/en-us/visualstudio/code-quality/ca1717?view=vs-2019) – julealgon Dec 11 '19 at 12:28

4 Answers4

33

There is a nice document that contains a lot of rules that you should follow to be in line with Microsoft: Framework Design Guidelines.

One thing that you should change: Do not name classes as their namespace. That will lead to compiler mixups. Just don't. Find a better name for either the class of the namespace.

Robert Harvey
  • 198,589
  • 55
  • 464
  • 673
nvoigt
  • 7,271
  • 3
  • 22
  • 26
  • 3
    The direct link to namespaces guidelines: https://msdn.microsoft.com/en-us/library/ms229026(v=vs.110).aspx – Pagotti Jan 18 '17 at 15:41
  • 2
    Which by coincidence or not is also the same name of a great book on the subject, also written by Microsoft people who participated in the creation of the DotNet framework, with several remarks about what they did right and where they got things wrong. Worth the read: https://www.amazon.com/Framework-Design-Guidelines-Conventions-Libraries/dp/0321545613 – Machado Jan 18 '17 at 15:53
  • @nvoigt, could you please edit your answer to add a quote from the link our friend Pagotti provided: "**DO NOT** use the same name for a namespace and a type in that namespace. For example, do not use Debug as a namespace name and then also provide a class named Debug in the same namespace. Several compilers require such types to be fully qualified." – Machado Jan 18 '17 at 15:59
  • 2
    Caveat: Sometimes a Product name is better than using a Company name. Been in a few scenarios where a company was bought out and we had to produce new namespaces across the board and re-release. I think this is very minor but wanted to point it out. – Jon Raynor Jan 18 '17 at 20:05
  • @Machado The MSDN guidelines are excerpted from the book you mentioned. – BJ Myers Jan 19 '17 at 00:33
  • 1
    Microsoft's framework design guidelines are highly questionable, contain false statements about how .NET works, and very often aren't followed by Microsoft itself. Their naming guidelines are good, but I would avoid linking the overall guidelines with a statement that "you should follow" them. – JounceCracklePop Jan 19 '17 at 08:13
  • @CarlLeth I consider no book a "bible" to be followed religiously to the letter. The guidelines aren't perfect, but for me they are "good enough" to recommend them to people. I think people will do better with those than with others or none at all. – nvoigt Jan 19 '17 at 08:26
  • @BJMyers, indeed, you're right. There's a remark on the website stating this. Thanks! – Machado Jan 20 '17 at 12:47
12

It's very difficult to determine how effective your naming strategy is in isolation from the rest of your code.

The namespace should give some idea where it fits in the broad structure of your codebase, and the class name would usually describe what sort of functionality or concept it represents within that area.

Caveats aside, in your specific example, if you're likely to have a lot more 'Util' type classes, I would consider putting them under Company.Utils.Maths etc. That way if you need to add functionality that's common to multiple utility areas, you already have a natural location for it.

richzilla
  • 1,083
  • 7
  • 11
  • 1
    That sounds like a good idea. Stop worry too much, just lob it all into "Company.Util". – user Jan 18 '17 at 15:24
6

It's been a while since I've worked with C# or the .NET ecosystem so I can't say what the current recommended best practices are. I'd recommend a change to your names like this:

Company
Company.Text
    public class TextUtils {...}
Company.Math
    public class MathUtils {...}
    public class ArbitraryPrecisionNumber {...}
    public class MathsNotation {...}
Company.SI
    public enum SISuffixes {...}
    public class SIUnits {...}

What I've done here is remove "Utils" from the namespace names. I think that "Util" should not be in a namespace, because the Company.Text namespace could one day contain classes that are not text utility classes. The Company.Math namespace already contains ArbitraryPrecisionNumber which Does not seem to be a "utility".

Removing "Util" from the namespace also clears up any confusion that might arise by having two things with the same name (as mentioned in Robert's answer: https://softwareengineering.stackexchange.com/a/340440/13156 )

Another way you could have organized the code:

Company
Company.Util
    public class TextUtils {...}
    public class MathUtils {...}
Company.Math
    public class ArbitraryPrecisionNumber {...}
    public class MathsNotation {...}
Company.SI
    public enum SISuffixes {...}
    public class SIUnits {...}

In this case, all of the utility classes reside in the same namespace. There is no more Company.Text namespace since the only thing there was a utility class.

Personally, I find the first option a bit more clear.

FrustratedWithFormsDesigner
  • 46,105
  • 7
  • 126
  • 176
5

Using the same name for the namespace and the class inside it is problematic.

  • If the namespace contains more than one class, why would other classes be put there? it doesn't feel right, because the goal of the name of the namespace is to describe all the classes within it, not just one. For instance, if you have JsonSerialization, BinarySerialization and XmlSerialization classes in a namespace, would it make sense to name your namespace XmlSerialization?

    What usually happens is that due to an extraction of a class from an existent namespace, or a merge between multiple classes or other reorganization, you find yourself with a namespace containing a major class; progressively, minor classes are put there because they are slightly related to the original class. For instance, a namespace LogParser may contain a single class LogParser, and then somebody puts LogConverter, because it's quite related to the parser, then LogSearcher, etc. The problem here is that the name of the namespace wasn't changed: as soon as LogConverter was added, the name should have been changed to LogsProcessing or, simply, Logs.

  • If the namespace contains only one class, it might be a sign of an issue within the code organization.

    While I've seen a few times the situations where a single class with proper SOLID principles was very different from anything else in the code base and was therefore put in a dedicated namespace, such cases are rare. More often, this is indicative of a problem. Similarly, nothing prevents you from having a class containing a single method, but more often than not, such classes would indicate a problem.

    Even if your namespace contains only one class, there is usually a way to be more specific when naming the class, and more general when naming the namespace. Imagine an application which, among other things, should at a given moment convert files written in ABC format to DEF format. The conversion doesn't require any deserialization/serialization to/from the business objects, and is done by applying a bunch of regular expressions which are short enough to be put within the conversion class itself called AbcToDefConverter. All the conversion logic takes about 80 LLOC in about ten interdependent methods—seems like a situation where there is absolutely no need neither to split the existent class, nor create additional classes. Since the remaining part of the application has nothing to do with conversions, the class cannot be grouped with other classes in existent namespaces. So one creates a namespace called AbcToDefConverter. While there is nothing inherently wrong in that, one could also use a more generic name, such as Converters. In languages such as Python, where shorter names are preferred and repetition is thrown upon, it may even become converters.Abc_To_Def.

Therefore, do use different names for namespaces than for the classes they contain. The name of a class should indicate what the class is doing, while the name of the namespace should highlight what's common in all the classes put within it.


By the way, utility classes are wrong by nature: instead of containing something specific, such as arbitrary precision arithmetic, they rather contain everything which hasn't found its way in other classes. This is simply bad naming, just as a Miscellaneous directory on a desktop—something which is indicative of the lack of organization.

Naming exists for a reason: to make your life easier when you need to find stuff later. You know that if you need to draw a chart, you may try to search for “chart” or “plot”. When you need to change the way an app generates invoices, you'll search for “invoic[e/ing]” or “bill”. Similarly, try to imagine a case where you'll say to yourself: “hm, this feature should probably be found in misc”. I can't.

Look at .NET Framework. Aren't most of those classes utility classes? I mean, they have few things to do with the business domain. If I work on a financial app, or an e-commerce website, or the next gen education platform, serializing XML or reading files or doing SQL queries or performing transactions is all utility stuff. However, they are not called UtilitySerialization or UtilityTransaction, and they are not in the Utility namespace. They have proper names, which make it possible (and easy, thanks .NET developers!) to find them when I need them.

The same comes for your classes you commonly reuse in your apps. They are not utility classes. They are classes which do certain things, and the things they do should actually be the names of the classes.

Imagine you created some code which deals with units and conversion of units. You may name it Utility and be hated by your colleagues; or you may name it Units and UnitsConversion.

Arseni Mourzenko
  • 134,780
  • 31
  • 343
  • 513
  • 7
    "Utility classes are wrong by nature". Interesting. What solution do you propose for something such as a Math function utility class? Should an *instance* of a Math object really be necessary to use functions beyond basic arithmetic operators? – FrustratedWithFormsDesigner Jan 18 '17 at 15:43
  • 1
    I agree with you, but what do you suggest as an alternative? – user Jan 18 '17 at 15:45
  • 1
    To be fair, on a lot of operating systems, a directory is just a special type of file (according to Unix philosophy, Unix systems treat folders as a special kind of file (on *nix systems, most functions that work with files (such as `mknod()` (except on Linux, which requires the use of `mkdir()` instead) or `stat()`) will see directories as files with the `S_IFDIR` mode flag; on Windows, a folder is a file with the "directory" attribute set), so it wouldn't seem _too_ unusual to me for the `File` namespace to contain directory tools. – Justin Time - Reinstate Monica Jan 18 '17 at 17:49
  • 2
    [I Shall Call It.. SomethingManager](https://blog.codinghorror.com/i-shall-call-it-somethingmanager/) – Ðаn Jan 18 '17 at 19:02
  • 4
    I delayed creating a "utils" library for the longest time but eventually you just have to give in. The alternative is having DLLs consisting of about 3 lines of code which is just cumbersome (and reminds me of the mess of dependencies node.js is), or copying and pasting your utility methods to every single class that might need them (to avoid having that "collection of random methods" class). IMO in the end it's a necessary evil. – Matti Virkkunen Jan 19 '17 at 01:17
  • 3
    @FrustratedWithFormsDesigner: simply... `Math`? I don't see how adding `Utility` suffix to everything would make our lives easier. When using .NET's `System.Math.Min()` method, would you really prefer writing `SystemUtility.MathUtility.Min()` instead? In all cases, I heavily edited my answer, so it should be clearer now. – Arseni Mourzenko Jan 19 '17 at 22:54
  • 2
    @JustinTime: good point. I changed the example used in my answer. – Arseni Mourzenko Jan 19 '17 at 22:54
  • @ArseniMourzenko: Yes, the first half of your answer is much clearer now. ...Whether or not the program unit containing all of your math functions contains the *word* "Utility" in its name, it is still a "utility"-type class, is it not? Or is it really just the *word* "Utility" that you object to, not the design and structure of such classes? – FrustratedWithFormsDesigner Jan 20 '17 at 15:08
  • 1
    @FrustratedWithFormsDesigner: if a class is called `LogConverterUtility`, then why not just `LogConverter`? What is then a class which is not an utility class? However, when the design and structure of an app leads to `Utility` word being meaningful, such as in “Let's put everything which is not business logic in `Utility` namespace,” then indeed the design itself is actually problematic. – Arseni Mourzenko Jan 20 '17 at 19:23