Editorial Note: I originally wrote this post for the NDepend blog. You can check out the original here, at their site. While you’re there, download NDepend and give it a try. If you like static analysis, you’ll find yourself hooked.
One of the things that has surprised me over the years is how infrequently people take advantage of customizable code metrics. I say this not from the perspective of a geek with an esoteric interest in a subject, wishing other people would share my interest; rather, I say this from the perspective of a businessman making money and wondering why I seem to have little competition.
As I’ve mentioned before, a segment of my consulting practice involves strategic code assessments that serve organizations in a number of ways. When I do this, the absolute most important differentiator is my ability to tailor metrics to the client and specific codebases on the fly. Anyone can walk in, install a tool, and say, “Yep, your cyclomatic complexity in this class is too high, as evidenced by this tool I installed saying, ‘your cyclomatic complexity in this class is too high.'” Not just anyone can come in and identify client-specific idiosyncrasies and back those findings with tangible data.
However, if they would invest some up-front learning time in how to create custom code metrics, they’d be a lot closer.
Being able to customize code metrics allows you to reason about code quality in very dynamic and targeted terms, and that’s valuable. However, you might think that unless you want a career in code base assessment, that value doesn’t apply to you. Let me assure you that it does, albeit not in quite as a direct way as it applies to me.
Custom code metrics can help make your team better, and they can do so in a variety of ways. Let’s take a look at a few.
Avoid Leveling Off
Sooner later in the life of your application or team, it happens. Someone on your team declares that it’s time to bring in an impartial, automated outsider to take a look at your code, and it happens. They install the judgmental interloper and it finds 24,981 issues with your code base. Sigh. Great.
But let’s also say that you do your due diligence, turning off some of the warnings that don’t interest you and adjusting the settings. Then, you diligently work on new and critical violations and, once those are fixed, you enable less and less critical warnings until, per the tool, you’ve whipped your code base into pretty good shape.
Great, no room for improvement anymore, right? Or, at least not until the tool vendor releases a new metric, which probably doesn’t happen very often.
This is where custom metrics make a difference. It’s all too easy to declare yourself victorious when you’ve slain the dragons in your code base pointed out by the tool. But that does not mean, by a long shot, that it’s time to cruise. Custom metrics let you define ways to continue improving.
I’ve just described how custom metrics can expand the focus when appropriate, but let’s also consider how they can narrow it for more targeted goals.
Perhaps you’re of the opinion that service classes should have a maximum of three fields (collaborators). Wouldn’t it be nice to have a custom metric that told you about the number of fields in service type classes? Or, perhaps you want all of the data transfer objects in a certain namespace to be immutable. Or how about wanting to see if any high fan-in methods had low test coverage? You get the idea.
Custom metrics let you define, ad hoc, what you would like to know about your code base, and then empower you to know it. In essence, custom metrics let you treat your code as data and give you power over selection and projection (filtering by row and column). This capability lets you target goals much more specific to your code than “let’s avoid methods that are too big.”
Level Up Your Code Review
Let’s say that your team has installed an analysis tool and become adept at customization. You’ve thus stopped the leveling-off problem and started to realize narrower focus on things that matter in your code. It’s not just the stats at build time that benefit. Your team members are gaining a skill, as well.
Assuming everyone is participating in the definition of custom metrics, they’re gaining experience actually generating them and they’re also gaining the experience reasoning about code by regarding it as data. They’re gaining experience at conceiving of important questions to ask about code quality.
As a result, you’ll find that code reviews move from “you forgot to add an underscore before that field name” to “it looks to me like this class is becoming dangerous to modify — let me run the composite danger metric that I’ve been working on.”
Your Team Is Unique
I’ll round out with a more philosophical concern, which is to say that your team is unique. The combination of personnel, domain, environment, organization, and many other factors ensures that there hasn’t been a team quite like yours previously. I’m not trying to suggest a one-world, “we’re all unique snowflakes” kind of thing, but rather to suggest that a one size fits all approach to evaluating your codebase does not make sense.
When obtaining static analysis tools, it is standard operating procedure to tweak the settings once they are installed. Most do this by allowing you to turn individual data points on or off, and some allow you to adjust thresholds and the like. Most teams take advantage of this to some degree and then call it a day.
However, given how much varies per team, that is rarely sufficient if you really want to capture the coding properties and characteristics that matter most to your team. Static analysis tools, out of the box, say things like, “That class has too many methods.” They don’t, out of the box, say things like, “Look, I know that Bob has been here a long time and gets testy about suggestions to the contrary, but it’d be better if at least the rest of us didn’t stuff all of our new methods into one of three massive singleton classes in the service layer.” Before you suggest that this is improbable, it is entirely possible to use custom metrics to flag augmented method counts in singletons by anyone not named Bob. The only thing that they can’t capture is “Bob’s a cranky long-timer.” At least, not yet.