What is elegant code? Everyone agrees that this is a rather subjective topic. I wrote down my take on this matter not so long ago. Almost every developer out there (an probably myself included) thinks that their own code is the greatest thing since sliced bread and that code written by other developers is just, well ... old bread with hair on it.
Inheriting the code base of some legacy application that needs to be extended with a ton of new features which should have gone into production yesterday. Sure, we all have our war stories as developers. The first thing we usually do in a situation like this is reading the code. Then after some (short) time, we start complaining against our peers and managers how bad this code base really is. In fact, managers have grown a special skin against this kind of complaints coming from developers. This kind of complaints are not taken seriously by anyone just because it seems like such a subjective matter.
Actually, a good code base that is easy to maintain is not that subjective anymore. Object-oriented design has many principles, like the Single Responsibility Principle and Separation of Concerns among many others, that exactly describe how good code should look like. In order to prove to ourselves and our managers that we are writing good code an that the inherited legacy application is bad, we have to come up with some cold, hard facts. Besides code reviews, static analysis tools are the next best thing to verify the quality of our code. Such tools, integrated with daily builds and continuous integration, can help you and your team to figure out how well your project is doing. Note that these are just tools and that code reviews are still a lot better at the time of this writing.
We are using FxCop for number of years now and we are very pleased with it, although writing custom rules is rather cumbersome and has a high threshold to my feeling, probably because it is not that well documented. However, the rules that ship out-of-the-box are OK most of the time, so we keep using it.
I briefly looked at Microsoft Source Analysis last weekend, but I really didn't like it.
A couple of months ago, Patrick Smacchia provided me a review copy of NDepend. I gave it a try last week and it literally blew me away. This tool performs a complete X-ray on the code base of your project and provides an extended report with a huge amount of information about the quality and maintainability of your project.
Actually, I briefly reviewed this tool when it was in an early beta a couple of years ago. For some reason (probably stupidity on my behalf), I dismissed this tool entirely. What a mistake! Good that I finally come to my senses.
I thought I'd unleash this power to Pet Shop 4.0. After creating the project, I already got a huge HTML file that contained a lot of information. Here is an example of a chart that shows the Abstractness versus Instability.
The X-axis shows the instability, that indicates how easy it is for the public interface of an assembly to change incorporating the number of other assemblies depending on it. The Y-Axis indicates the abstractness, i.e. how easy it is to extend the types in an assembly without a recompilation.
Notice that the PetShop.Model assembly is in the Zone of Pain. This means that it is used by a lot of other assemblies and that it is hard to extend the types that it contains. A couple of other assemblies are in the Zone of Uselessness, which means their types are very extensible but with few dependencies from other assemblies.
The report also contains a diagram that shows the dependencies between the different assemblies.
These diagrams are just a small part of the information that is contained by the report. When you close the report, you can use the NDependViewer application to further analyze the data.
<img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="329" alt="NDepend Screenshot 1" src="/assets/img/posts/ndepend-03.jpg width="430" border="0">
Now we come to the part where NDepend really shines: CQL or the Code Query Language. NDepend treats the code of your application as a database. With CQL you can perform all sorts of queries on its code base. NDepend already provides a lot of CQL queries out-of-the-box and also lets you write you own queries. It even has intellisense!
This gets my geek heart pounding. This means that there's a lot less friction involved when writing custom CQL queries as opposed to writing custom rules for FxCop. This particular CQL query returns the methods that have a Cyclomatic Complexity greater than 10, indicating that the OracleMembershipProvider needs some attention. When you double click one of the selected methods on the left, the code gets shown in Visual Studio. After a short inspection, it seems that the implementation of this class looks rather messy ("cough", understatement, "cough").
This is all just a tip of the iceberg. NDepend also lets you compare two different versions of your code base, performing CQL queries for determining the quality of the new code that was added. The latest version also supports test coverage metrics generated by NCover or Visual Studio. To make things even sweeter, NDepend ships with NAnt / MsBuild tasks letting you generate this information as part of your daily builds / continuous integration.
With this tool, we as developers can come up with the hard facts. It allows you to dig right into the problem areas of a particular code base. There is even a CQL query that indicates which particular methods need refactoring.
The documentation of this tool is just great, the home page is filled with short demo movies and make sure to check out the metrics definitions and the quick reference.
You might suspect that I'm getting paid for this post, but actually, I'm not. This is just another great tool in my tool bag, not a silver bullet. The hardest part of starting out with this tool is the first 15 minutes. When you give it a fair chance and get past those 15 minutes, it will all be worth it. Just amazing work! My two thumbs up.