Proactive monitoring of maintenance metrics
I tend to categorize Afferent and Efferent coupling as Maintenance metrics, meaning that these two copasetic metrics, in collaboration with Instability, Abstractness and coverage facilitate understanding how change will affect aspects of an architecture. One thing about metrics, though, is that they are only marginally useful as one time measurements. Real value comes from watching metrics over time and noticing trends. Once a baseline has been established (say for code coverage), then you can set goals and work to achieve them (like ensuring coverage doesn’t precipitously drop).
JDepend, a hip Java framework for determining Maintenance metrics, offers an interesting API that allows for proactive monitoring of its reported metrics. For example, imagine there is a particular package within an architecture that has become somewhat of maintenance issue due to its high responsibly. Because it has become heavily relied on (more so than originally intended), changes to classes within this package create a ripple effect throughout those classes which import it. By combining JDepend with JUnit (or even TestNG), a proactive monitor can be put into place that fails a test case should the Afferent coupling of a high risk package grow beyond a desired threshold.
Using JDepend’s smokin’ API is simple– just point JDepend at a project’s binaries and invoke the analyze method and voila– every metric gathered by JDepend is available for all analyzed packages. For example, becuase it’s my bag, the test case below analyzes a code base and asserts a bound for a particular metric.
package test.org.acme.bcg.metrics;
import jdepend.framework.JDepend;
import jdepend.framework.JavaPackage;
import junit.framework.TestCase;
public class AfferentCouplingTest extends TestCase {
private JDepend analyzer;
protected void setUp() throws Exception {
this.analyzer = new JDepend();
this.analyzer.addDirectory("./target/classes");
this.analyzer.addDirectory("./target/lib");
this.analyzer.analyze();
}
public void testAfferentness() throws Exception{
JavaPackage pck =
this.analyzer.getPackage("org.acme.bcg.impl.spring");
int afferentValue = pck.afferentCoupling();
assertTrue("package's afferent coupling has increased to "
+ afferentValue, afferentValue <= 27);
}
}
As you can see, the testAfferentness method ensures that if org.acme.bcg.impl.spring’s Afferent coupling grows beyond 27 the test case will fail.
Of course, this is a canary in a coal mine strategy, man– with this test case in place and your disco desire to limit the Afferent coupling of this package, it may be an opportune time to begin evaluating how to properly refactor the package so as to limit Afferent-ness. Dig it?
| Related odds and ends | ||
|---|---|---|
Friday 22 Sep 2006 | Code Metrics, JUnit
[...] Currying maximum favor with Groovy As a side project to building a small build results dashboard with Groovy, I found myself writing a copasetic application, which analyzed a code base using JDepend’s programmatic API. In both instances, I found myself needing to determine the maximum numeric value in a collection. Now, in Groovy (and in any language, for that matter), there is a cornucopia of ways to obtain a maximum value– either through brute force logic or more creatively hip mechanisms. [...]
If there’s a little code check you have in mind, an even easier way is to write a query with SemmleCode.
Free to download and free to use, SemmleCode is a new Eclipse plugin; it comes with a large library of pre-defined metrics and other quality checks. Thanks to its object-oriented query language, it is extremely to adapt queries to the specifics of your own project.
Check it out at http://semmle.com, and let us know what you think!
[disclosure: I'm the CEO of Semmle Ltd]