3

The project that raised this question is in C#, but it could apply to most languages that use namespaces.

I've read many things on good naming practices:

  • "Don't prefix your class names with their namespace name. That's just creating unnecessary duplication." (Smurf naming)

  • "One of the uses for namespaces is separating code and name collisions. Use them that way."

  • "When I'm reading code from a project and come across a class name, I want to know exactly which class is being referenced and not have to check which namespaces have been imported."

What I haven't been able to figure out is the best way to name classes in namespaces that perform similar tasks, but are completely independent from each other.

For example, let's say I have an audio codec library. The code in each codec namespace is not dependent on the others, but they all depend on a namespace containing common, generic code.

I might have classes like these. (Don't read too much into the names, they're only examples.)

Vorbis codec:

Project.Vorbis.VorbisEncoder
Project.Vorbis.VorbisDecoder
Project.Vorbis.VorbisFrame
Project.Vorbis.VorbisChannel
Project.Vorbis.VorbisParameters

ATRAC3+ codec:

Project.Atrac3P.Atrac3PEncoder
Project.Atrac3P.Atrac3PDecoder
Project.Atrac3P.Atrac3PFrame
Project.Atrac3P.Atrac3PChannel
Project.Atrac3P.Atrac3PParameters

IMA ADPCM codec:

Project.ImaAdpcm.ImaAdpcmEncoder
Project.ImaAdpcm.ImaAdpcmDecoder
Project.ImaAdpcm.ImaAdpcmFrame
Project.ImaAdpcm.ImaAdpcmChannel
Project.ImaAdpcm.ImaAdpcmParameters

Is this good design, or is it too repetitive? I don't like repeating the namespace name in the class name, but I don't know if that's preferable to duplicating class names like this:

Project.Vorbis.Encoder
Project.Atrac3P.Encoder
Project.ImaAdpcm.Encoder
0

2 Answers 2

4

As usual, that depends. It depends on the places where the unprefixed class names can be used. [Disclaimer: I'm a Java freak, but I think my experience will be applicable to C# as well.]

My rule of thumb is that symbols that are visible outside of their home namespace should have a unique name over all namespaces of the project.

If references to some Encoder will only show up in classes from the the same namespace, then, as a reader of the code, I'd expect the Encoder name to stand for the local one. In Java, I'd give the Encoder class a package-local visibility.

But if the Encoders are visible outside of their home namespace, I'd go for the long names.

E.g. Java has a negative example with the classes java.util.Date and java.sql.Date, which sometimes I had to use in the same method (bridging between core algorithm and database) - that forced me to use fully-qualified classnames at least for one of them :-(.

4
  • 1
    A unique name over all namespaces? Eeek! Not I - to each their own though, I suppose. (I thought namespaces were specifically to have to avoid doing that late 90s crap)
    – jleach
    Oct 17, 2017 at 17:42
  • 1
    Of course, that's what namespaces are for. But what I try to avoid is e.g. having 5 different classes of the same name and usage all over the project, so I either have to prefix their usage with the namespace or I have to guess (look at the imports) which class it is. Oct 17, 2017 at 18:01
  • As someone who programs in both Java and C#, I can see the advantage of this, but it would get quite unmanageable after a while. The namespaces have to be distinct between one another and the classes within a given namespace must be distinct from one another. Anything else goes I think.
    – Neil
    Oct 18, 2017 at 11:44
  • This ONLY applies to Java because Java either allows you to import a specific symbol (which then must have a locally unique name), or you must use the fully qualified name. So you get VorbisEncoder with import com.example.myapp.vorbis.VorbisEncoder or you have to spell out com.example.myapp.vorbis.Encoder each and every time. In languages with type aliases this does not apply.
    – amon
    Oct 20, 2017 at 10:05
3

Organization of a project can be somewhat subjective, but:

Namespace
Project.Codec

Maybe create a folder under codec called \Encoding

Classes and interfaces under \Encoding

IEncoder
VorbisEncoder : IEncoder
Atrac3Encoder : IEncoder

...And so forth. The sub folder is optional but if you have a lot of implementations of encoders, decoders, etc. it could be useful as a further organizational level for the project.

Finally, to import:

using Project.Codec.Encoding;

This would give you access to all the encoders.

1
  • In this particular example, each codec has a different API due to the differences in the audio formats. There is a set of classes that implement a common interface, as you described, to provide a "higher-level" API for each codec.
    – ABarney
    Oct 18, 2017 at 20:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.