NDepend – deep code metrics
23 June 2008 in .Net, Tools | Comments enabled
Generating code metrics is becoming more and more common with development tools these days – we’ve seen Visual Studio 2008 start to add some basic metrics such as cyclomatic complexity and “maintainability index”. This is all driven by an increased awareness of the difficulties of creating maintainable and reliable software as our software solutions become larger and more complex.
At Mindscape we even published some metrics about an earlier version of LightSpeed. I completely agree with Andrew’s comment that it would be beneficial for commercial software vendors to be more transparent about their code quality – especially when those vendors are providing developer tools. We’ll update our LightSpeed metrics on the Mindscape blog soon.
When it comes to deep code metrics I think you’d be hard pressed to find a more comprehensive tool than NDepend. NDepend is dedicated to code metrics and because of that dedication you’ll find you can spend days exploring everything this tool can do – I tell you this because this blog post will just scrap the surface of what can be done so I recommend you explore the tool yourself to find what parts you get the most value from.
NDepend ships with command line tools and CI integration tools but I’d recommend starting out by playing with the VisualNDepend tool. Here you can easily create a new NDepend project and add assemblies that you want to analyse.
Lets get some analysis done
So how do we start digging into the really meaty analysis? Hit F5, it’s go time!
This generated html file includes data about almost everything you could think of measuring. Basic information such as lines of code are presented first but aren’t off a huge amount of value.
Let’s have a look at a graph of abstractness vs. instability. This helps you quickly identify if your application is in the “Zone of pain” or the “Zone of uselessness”. Ideally you don’t want to be in either and want to ride the fine line between the two. Here’s the break down for LightSpeed and the LightSpeed LINQ provider:
I’m pretty comfortable with that – we’re in the green zone!
What does this mean?
- Stability means that there are a lot of dependencies on an assembly.
- Abstract means that the assembly is very extensible.
So we would end up in the zone of pain if we have a very stable assembly but it’s not extensible. You can imagine working with such a project – any changes have a huge ripple effect and if you’re working with the a project depending on it, you have very little ability to actual alter the behavior of that dependency.
Conversely, we end up in the zone of uselessness when an assembly is very extensible but nobody is actually using it (no dependencies upon it).
LightSpeed assemblies seem not to be depended on by other assemblies (I excluded the 10+ Unit Test libraries for this) and aren’t overly abstract. This is by design – we do have a rich API but you don’t really want to be fiddling in the absolute core of the product so we’ve tucked away some parts to keep the public API simple and easy to use.
The power of CQL
You tend to know that a product is sophisticated when it includes its own query language and NDepend doesn’t let us down here. CQL allows us to write queries for measuring metrics – for example, we might want to display a warning when a method has too many lines of code, or where cyclomatic complexity exceeds certain levels.
NDepend ships with several of these rules already enabled and some of them have been tripped in our LightSpeed analysis. For example, we have several methods with more than 30 lines of code. That can be useful for identifying areas of our code base that might be worth refactoring.
// <Name>Methods too big (NbLinesOfCode)</Name> WARN IF Count > 0 IN SELECT TOP 10 METHODS WHERE NbLinesOfCode > 30 ORDER BY NbLinesOfCode DESC
I’d recommend having a play with CQL to write your own queries especially if you’re using CI (you are using Continuous Integration right?) as you can hook NDepend to report warnings.
Visual dependency graph
One area that I’ve found useful with NDepend is the ability to more visually see a dependency hierarchy and better see how your projects fit into the software ecosystem in which they have been developed.
Here’s the output for LightSpeed + LightSpeed.Linq
We can see here the usual suspects – System, System.Data etc but we can also identify other assemblies that might not be obvious. For example, LightSpeed provides support for talking to SQL Server, MySQL, PostgreSQL, SQLite, VistaDB and Oracle and the caching can leverage Memcached or the caching provider in System.Web.
I could certainly see this feature being of use to developers picking up an existing project as it would certainly aid understanding the structure more quickly and efficiently.
There is considerably more information provided by NDepend and I’ve only covered a few areas that I found most interesting in this review. There is a free version for trial/academic/open source users and a professional version also available. I highly recommend grabbing a trial and exploring your projects – you might be a surprise.
The key with any metrics is knowing how to interpret them and understanding the action that you can take to improve them. My suggestion would be to download the trial, run the analyzer over your code and identify some areas of concern, fix them and then recheck. Continue this cycle for the duration of your trial and I’m sure you’ll find you’re producing better code because of it – something we should all be endeavoring to do.
Go and grab NDepend and start improving your code.