Getting Up-to-Speed on NDepend and Code Metrics
Any tool is only good if it is in the hands of a developer who knows how to use it. NDepend is one of those tools which is very powerful but addresses an aspect of software development too few architects or developers understand, software metrics.
We talked with Patrick Smacchia, from the NDepend team, back in January of this year to understand what the product NDepend was and how it can be used to help build better software. NDepend has gone through some updates since our talk and boasts many features:
- Code Query Language (CQL)
- Compare Builds
- 82 code metrics
- Manage Complexity and Dependencies
- Detect Dependency Cycles
- Harness Test Coverage Data
- Enforce Immutability and Purity
- Warnings about the health of your Build Process
- Generate custom report from your Build Process
- Facilities to cope with real-world environment
Andre Loker, a .NET developer from Germany, recently produced a great tutorial on using NDepend from a developer's perspective. Andre's tutorial reviews what NDepend can do for your team, what to expect from the tool and how to make the best use of it. NDepend's Metrics are of particular interest:
- Afferent coupling (Ca)
This metric desribes the number of types or methods from outside of the current assembly that use a given type or method. The higher this value, the more important the given type or method is to users of the assembly.
- Efferent coupling (Ce)
This is the counterpart of Ca: it describes the number of assembly external types/methods that a specific type/method uses. A high value indicates that the specific type/method is very dependent on the external assembly.
- Relational cohesion (H)
A metric that describes how strong the types within a single assembly are related to each other. Generally, types within an assembly should be strongly related, but not too strong.
- Instability (I)
This describes how sensitive an assembly is regarding changes ion assemblies it depends on. It is measured as the quotient of efferent coupling (Ce) and total coupling (Ca+Ce).
- Abstractness (A)
Describes the ratio of abstract types in an assembly.
- Distance from main sequence (D)
Instability and abstractness should be in a certain balance. With my own words, I would describe this balance like that: an assembly with high abstractness should be stable as it is most likely used as an input assembly for other assemblies. If it were instable, it would be likely that it has to change sooner or later and this change would ripple through all assembly that depend on this assembly. On the other hand, a very concrete assembly (low abstractness) is likely to be at the end of a dependency graph, that is, almost no assemblies depend on it. It can and will therefore be quite instable.
- Lack of cohesion (LCOM)
In a coherent class, most of the methods will deal with most of the fields of that class. If you find that many methods in the class deal only with a subset of the fields it might be an indicator that the responsibility of the class is too broad and the class should be split.
- Cyclomatic complexity (CC)
This metric describes how many pathes a method has. The control flow in a method branches at every conditional statement, loop and other statements. A method with a high CC is hard to maintain.
Andre covers all the aspects of using NDepend from the ground up, assuming the user is not familiar with the tool at all. He utilizes NDepend to start the user from the beginning:
Create a Project
Creating a project is easy and can be done in one of two modes:
Visual NDepend supports two operation modes which only differ in the fact whether you explicitly create a project file or not: if you just want to do a quick analysis, simply select the menu point "Select .NET assemblies". This will allow you to perform the analysis without creating an explicit project file.The other option is to create an explicit project. This is of course recommended if you need to perform the analysis more than one time (eg. in continuous builds).
Once all of the assemblies are select Run Analysis to start the process.
This is what NDepend is all about, the various windows displayed the tutorial really helps define what NDepend is conveying. Each window provide key pieces of information:
- Class Browser
Andre really likes this part of NDepend to report almost any information on the assemblies:
Let me put it straight: this feature is just awesome! NDepend spits out a lot of metrics on its own, but it also gives you a powerful query language that you can use to gather almost any information about your source code that you like.
CQL (Code Query Language) is a query language similar to SQL - which is the first cool thing as most of us are used to SQL. Using CQL you can query against a large set of metrics. Have a look at the CQL specifications to see how complex the query language is.
To give you an example of a simple CQL query:1: SELECT TYPES WHERE NbFields > 6
CQL resembles the T-SQL queries many developers use on a daily basis so learning CQL is pretty easy.
The results of analyzing project assemblies and having them saved statically in HTML provides a very good way to know the state of the project at that point in time. The tutorial points out the important metrics kept in the report:
- General application metrics
- lines of code
- number of IL instructions
- number of lines with comment, percentage comments
- number of assemblies, types, classes, interfaces, structs, etc.
- Percentage of public types and methods etc.
- Average number of fields per type, method per type etc.
- Metrics per assembly
- LOC, number of IL instructions, ...
- coupling metrics (Ca, Ce, relational cohesion, instability, abstractness, instability-abstractness-balance)
- Assembly dependencies
- CQL query & constraints results
- Warnings for constraints that have failed
- Type metrics
- LOC, number of IL instructions, ...
- coupling metrics (Ca, Ce, lack of cohesion ...)
- cyclomatic complexity
- Number of directly and indirectly derived classes, depth in inheritance tree
- Type dependencies (initially not enabled)
- Defines which types depend on which types.
The report also contains a dependency view (as in the Metrics window in Visual NDepend), a dependency graph (again, no 64bit support) and graph that show the balance between abstractness and stability.