45

I have read Uncle Bob's Clean Code a few months ago, and it has had a profound impact on the way I write code. Even if it seemed like he was repeating things that every programmer should know, putting them all together and putting them into practice does result in much cleaner code. In particular, I found breaking up large functions into many tiny functions, and breaking up large classes into many tiny classes to be incredibly useful.

Now for the question. The book's examples are all in Java, while I have been working in C++ for the past several years. How would the ideas in Clean Code extend to the use of namespaces, which do not exist in Java? (Yes, I know about the Java packages, but it is not really the same.)

Does it make sense to apply the idea of creating many tiny entities, each with a clearly define responsibility, to namespaces? Should a small group of related classes always be wrapped in a namespace? Is this the way to manage the complexity of having lots of tiny classes, or would the cost of managing lots of namespaces be prohibitive?

Edit: My question is answered in this Wikipedia entry about Package Principles.

3
  • 11
    Another example of a good, and real-world developer question closed. If this isn't the stackexchange site to ask about developer best practices, what is? Dec 30, 2013 at 15:10
  • @SamGoldberg: it gets better. I found a good answer to this question here: en.wikipedia.org/wiki/Package_Principles. I posted this answer, and a moderator deleted it, because I simply posted the link and didn't have the time to copy/paste the content.
    – Dima
    Dec 30, 2013 at 16:04
  • 2
    I think my only critique of the question would be, instead of asking multiple questions at the end, try to summarize it into one single question, e.g. "what should be the criteria to determine whether items should be in the same namespace or different namespaces?". Dec 30, 2013 at 17:15

5 Answers 5

26

(I have not read Clean Code and don't know much Java.)

Does it make sense to apply the idea of creating many tiny entities, each with a clearly define responsibility, to namespaces?

Yes, just as it does with refactoring into multiple classes and multiple functions.

Should a small group of related classes always be wrapped in a namespace?

Without actually answering: yes, you should at least use one top-level namespace. This can be based on project, organization, or whatever you like, but using few global names will reduce name conflicts. A single namespace to group everything else under it only introduces one global name. (Excepting extern "C" functions, but that's due to C interoperability and only affects other extern "C" functions.)

Should a small group of related classes be wrapped in a namespace dedicated to them? Probably. Especially if you find yourself using a common prefix on those classes – FrobberThing, FrobberThang, FrobberDoohickey – you should consider a namespace – frobber::Thing and so on. This would still be under your root namespace or another namespace if they are part of a larger project.

Is this the way to manage the complexity of having lots of tiny classes, or would the cost of managing lots of namespaces be prohibitive?

Taking the above example of prefixed names, it isn't harder to manage frobber::Thing than FrobberThing. It may even be easier with some tools, such as documentation and code completion. There is a difference with ADL, but this can work in your favor: fewer names in associated namespaces make ADL simpler to figure out, and you can put using declarations to inject specific names into one namespace or another.

Namespace aliases allow you to use a shorter name for a longer namespace in a specific context, which again allow easier use:

void f() {
  namespace CWVLN = Company_with_very_long_name;  // Example from the standard.
  // In this scope, use CWVLN::name instead of Company_with_very_long_name::name.
  namespace fs = boost::filesystem;  // Commonly used.
}

Consider Boost, which has a single root namespace, boost, and then many subnamespaces – boost::asio, boost::io, boost::filesystem, boost::tuples, etc. – for various libraries. Some names are "promoted" to the root namespace:

All definitions are in namespace ::boost::tuples, but the most common names are lifted to namespace ::boost with using declarations. These names are: tuple, make_tuple, tie and get. Further, ref and cref are defined directly under the ::boost namespace.

The biggest difference from languages with "real" modules is how common it is to use a flatter structure, which mostly happens because that's how it works unless you take extra, specific effort to define nested names.

1
  • +1 @Fred Nurk for the full analysis instead of one line answers. You don't have to read the book to know what the question is about. This comment thread exposes the concepts and differences that a C++ and a Java programmer might have on this book.Clean Code comment in Amazon
    – Marlon
    Aug 18, 2011 at 5:20
11

You should have one master namespace for all your code. This distinguishes it from external code with regards to namespaces.

Within your master namespace, dependent on the size and complexity, you may open sub-namespaces. This is where names clearly mean something within a context, and the same names might be used within a different context.

In particular if you have a generic sounding name like FileInfo that means something particular within a context, put it in a namespace.

You can also use a class for this, although a class is not extensible so you cannot add new declarations to the class without modifying its header.

3

Namespaces isn't a Module concept so I would use them only where name conflicts could occur.

5
  • 4
    Not sure what you mean. Why would a set of related classes wrapped in a namespace not be a module?
    – Dima
    Feb 21, 2011 at 13:15
  • There are no restrictions within the namespace. In a module you can say that a given class, function or variable can only accessed from inside of the module. In a namespace this is not possible it is just a prefix to the name.
    – Brainlag
    Feb 21, 2011 at 13:26
  • 3
    Looks like we disagree on the definition of a module. To me anything that groups related entities together and has a descriptive name is a module, regardless of wither or not it provides encapsulation.
    – Dima
    Feb 21, 2011 at 13:32
  • 3
    Access restriction is orthogonal to modules. In fact, you have successful systems like Python's which definitely are more "module-like" than C++'s namespaces, but impose no access restrictions at all.
    – Fred Nurk
    Feb 21, 2011 at 13:45
  • I believe this is one of the best practices listed on Scott Meyer's books
    – Raphael
    Feb 21, 2011 at 13:53
1

Java has namespaces, they just aren't really called that. In javax.swing.* javax is a namespace and swing is a sub-namespace. I haven't read the book to know what it says about java packages, but the same principles would apply pretty much directly to namespaces in any language.

A good heuristic is you use a namespace when you find yourself wanting to type the same prefix for classes over and over. For example, I recently wrote some classes called OmciAttribute, OmciAlarm, OmciMe, etc. and realized I needed to break Omci into its own namespace.

1

I like deep namespaces (which usually means three levels).

  • I have the company name.
  • app/util/lib/etc
  • Project Name/ or Package as appropriate

Depending on situation I may have one more level

  • details (Platform specific implementation details)
  • utils (utility object that have not been moved to general utility yet).
  • whatever I need.

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