Should I use (otherwise optimal) class names that

2019-06-15 18:49发布

问题:

This situation probably is not entirely uncommon to some of you: you have some functionality to put in a class but the perfect name (*) for that class is taken by one of the classes in the System namespace or other namespace/class that's not yours but you're using/importing.

(*) By perfect I mean small, concise and clear names.

For instance I have an Utils class that has a Diagnostics (mostly debug utils) class and a Drawing class. I could:

  1. have a DrawingUtils class and a DiagnosticsUtils class, but that just smells like bad structure.
  2. pick a thesaurus and be done with an worse, longer or awkward name that's casually still not taken.
  3. Write class names in my native language instead of English.
  4. Ask the smart guys at StackOverflow.

I think options 1-3 aren't promising :(

EDIT:

Since my chosen answer doesn't address the problem definitively (neither I do), what I'd recommend for people facing the same situation is to ask yourselves: Will you frequently use the conflicting BCL class/namespace? If no, then let your name conflict (as I did with Diagnostics). If yes, add a word that limits the possibilities of your class/namespace.

In practice, this means:
"Drawing": Something that draws.
"MyCustomControlDrawing": Something that draws only on MyCustomControl. e.g.: "WidgetDrawing".

EDIT2:

Another solution to take a look next time: Extension Methods (courtesy of Lawnmower).

回答1:

Use namespaces to disambiguate your classes from the classes in other namespaces. Either use fully qualified names or a using statement that tells the compile what you need:

using Type = MyReallyCoolCustomReflector.Type;

Now if you want to still use the Type class from the System namespace:

System.Type sysType = anObject.GetType();

Generally I try to avoid name duplicates but this doesn't always work out that way. I also like simple, readable and maintainable code. So as often it is a trade-off decision.



回答2:

I don't see any issue with keeping the names Drawing, Diagnostics etc. That's one of the purposes of namespaces, to resolve naming conflicts.



回答3:

The beauty of namespaces is that they allow you to create classes with identical names. You can assign an alias to a namespace when you import it into your file with a using statement.

using MyAlias = My.Custom.Namespace;

this will keep your classes separate from Microsoft's.

you can then reference your classes as

MyAlias.Diagnostics

or you could alternatively assign an alias to Microsoft's namespace, but I wouldn't recommend this because it would confuse other developers.



回答4:

To me, it really isn't worth the hassle of purposefully writing conflicting class names. You'll confuse other developers who aren't familiar with your codebase, because they will be expecting to use BCL classes but end up with yours instead (or vice versa). Then, you just waste their time when they have to write specific using aliases.

Honestly, coming up meaningful identifier names is a useful skill, but it isn't worth delaying your development. If you can't come up with something good quickly, settle for something mediocre and move on. There is little value in toiling over the names. I dare say there are more productive things you could be doing.

EDIT: I also don't believe that "small" is a component of a "perfect" identifier. Concise and clear, for sure, but if it takes a longer name to convey the purpose of a particular construct, so be it. We have intellisense, after all.



回答5:

Well, if you want to avoid a namespace collision there are a couple of things you can do:


  • Don't collide, instead choose a unique name.

Example:

If you are creating a Math class you can name yours CamiloMartin.MathHelper


  • Use the long namespace to distinguish between collissions.

Example:

public class MyClass
{
    public int SomeCalculation(int a, int b)
    {
        return MyNamespace.Math.SomeFunc(a, b);
    }
}

  • Using an alias to differentiate.

Example:

using System.Math;
using SuperMath = MyNamespace.Math;

namespace MyNamespace
{
    public class MyClass
    {
        public int SomeCalc(int a, int b)
        {
             int result = Math.abs(a);
             result = SuperMath::SomeFunc(a, b);

             return result;
        }
    }
}


回答6:

Just for the record: .NET framework doesn't have neither Utils nor Diagnostics class. (But does have System.Diagnostics namespace.)

Personally I don't like general-purpose classes like Utils because their methods are not very discoverable (and usually either too general or too specific), therefore I would justify their use only as for internal classes.

As for the rest -- I agree with others on that namespaces are convenient. (Although I would thought twice to name the class if there is already a class in System with the same name, not because of name conflicts, but rather because the reason why I can't use 'original' class could mean that the class I'm about to create is semantically different.)



回答7:

Often its possible to choose a more specific name. Take Utils for example. Absolutely everything can be called a utilitiy. For the reader of your code this classname is worthless.

Often utility classes are a collection of methods that didn't really fit anywhere else. Try to place them where they belong, or group them by some criteria, then use the group as a classname. Such grouping is in my experience always possible.

In general:

  1. That's what we are doing (hey, we can refactor it later)

  2. Used it once or twice but only on important classes. Especially useful if you don't know the 'perfect' name yet.

  3. don't even think about this...

Using namespace aliases is no fun. So I avoid it if I can.