Hierarchical Namespace Component

Share/Bookmark

Modeling components of a code base with namespaces is a much better idea than modeling them with assemblies. I wrote about the namespaces vs. assemblies debate in the past (Control components dependencies to gain clear architecture). The fact is that namespace is a logical artifact while assembly is a physical artifact. Of course, creating assemblies to partition parts of the code that at runtime physically don’t live within the same AppDomain is a good thing. I explained that in Advices on partitioning code through .NET assemblies. Unfortunately, the vast majority of .NET teams use assemblies instead of namespaces to partition logically their code. They end up with hundreds of Visual Studio projects:

  • Hundreds of VS projects organized through dozens of VS solutions is something hard to manage.
  • These hundreds of projects takes a lot of extra time to be compiled (because of the repetitive tier assemblies parsing).  By extra time I mean that the compilation takes minutes instead of seconds!
  • And finally, loading all these assemblies at runtime slow down consequently the startup time of applications. Indeed, doing so multiply the unit overhead that the CLR needs to load an assembly. The overhead is mainly due to CAS security checks, cryptographic signing check, and IO file read.

In order to model logical components, the logical nature of namespace is a preemptive advantage over the physical nature of assembly. However namespace have a second awesome characteristic: they can be declared hierarchically. So namespaces can be use to modelize a hierarchy of components. Today I would like to ramble on some consequences and caveat of organizing hierarchically components.

Theory: Tree vs. Flat view

This hierarchical way of componentizing code is something that we took account early in the NDepend development. At any time, the user can choose to display namespaces through tree (i.e through a hierarchy)…

…or to display flat namespaces:

Personally I prefer the tree option. After all, why do developers naturally partition the code? Because of the need to organize code and API through some smaller chunks. Smaller chunks are naturally easier to develop, understand, maintain, test and debug. This is the famous divide and conquer tenet.
 
But when the code base is consequently growing developers are facing a dilemma:

  • Smaller components are easier to be managed one by one. But this implies to deal with hundreds of components. As a consequence the big picture becomes messy.
  • Keeping a small number of components force to have large components. While the big picture remain understandable, larger components are harder to manage.

This is why developers apply recursively the divide and conquer idea. As a result, they obtain a hierarchical organization of code.

Practice: Tree vs. Flat view

These 2 dependency graphs illustrate well the point. The first one is made of the 52 namespaces declared in the mscorlib (this is the flat view).

The second one is made of the 16 root namespaces of the DLL mscorlib (this is the root tree view). The root tree view present less information than the flat view, but at least it is readable.

Moreover the root tree view is a good start to dig into the code and browse nested namespaces inter-dependency:

The same phenomenon appears with the Dependency Matrix. The root tree view (first matrix) is a better way to browse the code than the flat view (second matrix).


Component Hierarchy and Dependency Cycle

Avoiding cycles between components is an essential point to care for, in order to keep a code base maintainable. I detailed that in the post: Maintainability, Learnability, Component, Layering. When components are hierarchically organized, some non-trivial cycles can appear. Let’s look at a small example.
 
If we look at the dependency between the 3 following namespaces we won’t find any cycles:

namespace ParentA.Child1 {
public class ClassA1 { private ParentB.ClassB m_Field; }
}
namespace ParentA.Child2 {
public class ClassA2 { }
}
namespace ParentB {
public class ClassB { private ParentA.Child2.ClassA2 m_Field; }
}

There is no cycle, this is clear from the flat dependency view,

This is what I called a non-trivial cycle because a cycle exists while there are no cycles between namespaces. The fact is that RootA.* is not considered as a namespace because it doesn’t contain directly any class. In our internal NDepend terminology we named RootA.* a namespace container. Technically your code is entangled and contain a cycle even if physically there is no cycle between namespaces!

Hierarchical components constitute a powerful way to partition code but be aware that some non-trivial entangling cases might appear. In a next post, I’ll expose a cool way to use hierarchical componentization effectively in the real world.

Share/Bookmark

This entry was posted in Dependencies, Dependency Cycle, Flat view, Hierarchical components, Tree view. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Alan G

    Patrick,

    question for you, if I’m understanding correctly, whilst NDepend can support analysis at the namespace level it favours assemblies. For example, the NDepend report includes a graph of stability vs abstractness – I can’t find a way to repeat that at the namespace level?

    Would be useful to allow a “toggle” to switch the focus from assembly to namespace and back…

    Regards,
    Alan

  • http://codebetter.com/members/Patrick-Smacchia/default.aspx Patrick Smacchia

    Chris A, it was a mistake, it is fixed, thanks!

  • Chris A

    Do the meanings of modelize and modelizing differ in some way from the meanings of model and modeling or is this just a mistake?

  • http://codebetter.com/members/Patrick-Smacchia/default.aspx Patrick Smacchia

    Petar, a picture is worth a thousand words. When it comes to talk about dependencies\structure\architecture\organization\components in a code base, dependency graph and dependency matrix are certainly the most appropriate tool.

    Everybody can read a dependency graph. Concerning dependency matrix, I agree with you, the overall interpretation is less obvious. But the fact is that dependency matrix is a much more efficient way than graph to represent dependency. This is why I wrote some posts like this one: Identify Code Structure Patterns at a Glance

    Read this post, download the trial version of NDepend. try it on your code base, and learn how dependency Matrix can be useful to you. After all, programmers should continuously learn new tooling, aren’t we?

  • http://ppetrov.wordpress.com/ Petar Petrov

    Petrick, I think you are the only one that understand all this information. What all this numbers means ? Is this graphs useful for someone ? Honestly I don’t know. maybe a simple scenario(s) to demonstrate and explain separate features will be more useful.
    Just my 2 cents.

  • fschwiet

    I started doing TDD and the first thing I noticed is I have a lot of small classes to organize. At first I tried to organize them into namespaces, but this required foresight and that thinking slowed me down. I was never too happy with the result either.
    Well all classes are exposed via an Inversion-of-Control container, and IOC container knows every registered class and its dependencies. So what I do now is generate a treeview of whats been registered with the IOC container. I really like it as I can code away, add new classes, defining their immediate relationships without worrying or thinking about where they fit in the big picture. Then I generate the hierarchical view that shows the big picture view for when I need to reorient myself.
    I’m really happy with the result.

  • http://codebetter.com/members/Patrick-Smacchia/default.aspx Patrick Smacchia

    >You sacrifice some potential performance (there ways around this)

    Not really, I saw in the real-world some compile times dramatically slowing down, something like 2mn instead of 4 seconds (no kidding)! The impact on the developer productivity is huge.

  • http://bjarte.com BjartN

    In some organizations I believe that separating the code into projects is the best approach to organizing your components. Organizing the code this way makes the components more explicit and real to people that really don’t care that much about design. These people do exist. You sacrifice some potential performance (there ways around this) do make your components more explicit and physical.

    From a theoretical point of view I agree that namespace separation is the best way to go, and armed with NDepend you can do a lot of good analysis.