There are many tools available to provide developers with metrics to help determine the quality of the code they are writing. However, there are situations where using tools in isolation, or not understanding the subtleties of the data they are giving you can result in indications that your code quality is higher than it actually is. This is especially true when tools are run over large bodies of legacy code.
This can be best demonstrated using an example:
JDepend is a free tool that ‘traverses Java class file directories and generates design quality metrics for each Java package’ (there is also a plug-in for Eclipse users). It is a good tool that helps detect smells such as high coupling and circular dependencies. No matter how good the tool is though, its results can be misinterpreted.
One of the features of JDepend is to show a graph that represents each package’s ‘Distance from the main sequence’. This metric is an indicator of the package’s balance between abstractness and stability and can help you get a sense of the maintainability of the package in the future. The values range from 0-1, with 0 representing highly unstable packages and 1 representing stable packages. (For more explanation of these types of metrics, see Andy Glover’s article on coupling metrics here.)
The screenshot below shows a selection of packages from the Jedit project (used for example purposes only). The packages with green dots on the graph show a close balance between abstractness and stability, while the one black dot represents a more unstable package that I may want to investigate further.

Narrowing it down, I quickly find the offending package and to appease my boss (who wants all code to have green dots) I can game the results of JDepend by simply adding an empty Interface to the package, thereby increasing its abstractness value which results in the package moving closer to the Main Sequence:
Adding an empty interface to a package just to satisfy a metric adds redundant code, looks ugly and is, well, plain stupid. I don’t believe anyone would actually do this to satisfy a green dot on a graph.
The reason I use this example is this. Imagine running a tool like JDepend over some legacy code to determine whether the code needs refactoring or a redesign for quality purposes (e.g. near the end of the project). If all the packages show a green result on the graph, can you be satisfied that your code is of high quality? Not really, as you are probably only looking for code that fails to satisfy these thresholds, rather than looking more closely for reasons why the ones that pass do pass.
Can we trust these tools to give us reliable metrics on the quality of our code? Is the practice of using these tools a waste of time? The answer to both these questions is a resounding ‘No!’
When using a tool, any tool, you must truly understand the details of what the tool actually does, look behind the raw information it gives and put the results in context. Using JDepend, does a Coupling ratio of 3 mean your code is great quality or full of bugs? How do you know, unless you understand the context of the code and package? Also, this tool is not actually telling you whether what it is reporting is good or bad, but giving you the information to investigate and decide for yourself. This is an important point as sometimes these types of tools are misinterpreted (or marketed) as providing a high/low quality mark, when really they are not. Therein lies the danger of using colored icons such as black, red or green dots.
In this example, it would be better to run JDepend after a static code analyzer (again, properly understood and configured). That way, the analyzer can detect issues such as empty code blocks or interfaces and unused imports, and eliminate them before running JDepend.
1 comment »