Adding Static Analysis to Your Team’s DNA
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 play with adding it to your team’s build.
Stop me if this sounds familiar. (Well, not literally. I realize that asynchronous publication makes it hard for you to actually stop me as I type. Indulge me the figure of speech.) You work on a codebase for a long time, all the while having the foreboding sense of growing messiness. One day, perhaps when you have a bit of extra time, you download a static analyzer to tell you “how bad.”
Then you have an experience like a holiday-time binge eater getting on a scale on January 1st. As the tool crunches its results, you wince in anticipation. Next, you get the results, get depressed, and then get busy correcting them. Unlike shedding those holiday pounds, you can often fix the most egregious errors in your codebase in a matter of days. So you make those fixes, pat yourself on the back, and forget all about the static analyzer, perhaps letting your trial expire or leaving it to sit on the shelf.
If you’re wondering how I got in your head, consider that I see this pattern in client shops frequently. They regard static analysis as a one time cleanup effort, to be implemented as a small project every now and then. Then, they resolve to carry the learning forward to avoid making similar mistakes. But, in a vacuum, they rarely do.
A Better Course of Action: Incorporate the Tool
For the remainder of the post, I’ll refer to NDepend, both because of my familiarity with it and because it seems entirely appropriate for the NDepend blog. But the principles here could apply to many static analyzers or other types of tools.
Simply put, you should not forget the tool. On the contrary, you should expand your relationship with it. You should add it to your build and to your process as a developer.
This approach requires very little effort. At a bare minimum, you can modify your build to generate a report and run the tool prior to each commit. Doing this tightly integrates code quality and trends into your development process. They become constant fixtures, rather than periodic, one-off projects.
But that covers the “how” and not so much the “why.” Let’s address that in the remainder of the post. What benefits do you realize from using NDepend on a continuous basis?
An Important Culture Shift
First and foremost, consider what happens when you tightly integrate a concern code quality where none had previously existed. When you download a static analyzer for a legacy codebase or for a project where things have gotten ugly, you evoke the image of someone going to the dentist after a tooth rots out of his head. Not having seen a dentist in years or ever cared about oral hygiene, this patient seeks a significant damage report followed by invasive remediation.
But what if that same patient had just brushed and flossed all along?
You now have a chance to turn your group into one of brushers and flossers. No better time exists to change habits than after a massive cleanup effort. Shifting back to software development, you’ve scrubbed your code into great shape as part of a large effort. By keeping the tool in place and continuing to use it, you can build on that momentum.
Continuous Skill Improvement
When you change the culture of the group, you set the stage for individual improvement as well. With an analyzer like NDepend in place and running in everyone’s Visual Studio and with each build, the team starts to pay attention to new things.
“Why did our average cyclomatic complexity spike in the last couple of weeks?” “How did that dependency cycle get introduced yesterday?”
Notice the mention of relatively short time frames in these questions. This occurs because continuous use of NDepend has shortened the feedback loop for caring about architectural and quality matters. The team pays more attention because these issues have more visibility. And they get better at understanding cause and effect because less time elapses between action and perception of outcome.
This has the cumulative effect of promoting learning for individuals. Team members learn at a much quicker rate the difference between good and bad code.
Improved Reasoning about Code and Architecture
The realized improvement eventually transcends even good and bad code, however. Sure, those make for good starting points. Out of the box, NDepend presents a series of straightforward rules, like “base classes should not use their derivatives” and “avoid classes with too many fields.” Never previously aware of those concerns, the team quickly learns about them when the feedback loop tightens.
Eventually, however, they’ll write code that mostly complies with the out of the box rules (and non compliance will represent a deliberate choice rather than an accident). Luckily, the benefit to the team doesn’t stop there.
With NDepend, you have strong visualization tools and the ability to use CQLinq to create custom queries. Combined, these two features offer unlimited ability to continue advancing understanding of code.
The graphs, heat maps, and charts allow you to visualize the application architecture in a powerful way. The team no longer has to settle for assuming the architecture lines up with some Visio diagram of a layer cake made years ago. They can generate a “reality” picture.
And with CQLinq, they can interrogate the codebase about anything they choose. That can mean tightening the threshold on existing rules about quality, or it can mean using what they’ve learned from the tool to create their own composite metrics and rules about the code.
Practice Makes Perfect
I see clients make reactive pushes for quality all the time. Some release goes out with an embarrassing number of bugs, or some feature addition gets way behind schedule “because technical debt.” This prompts a panic about the quality and state of the codebase, I get a phone call, money changes hands, and suddenly I’m peering at unfamiliar source code to make recommendations.
NDepend helps me a great deal with those recommendations. It gets me right to the source of the woes and then it helps me produce visualization aids for technical and non-technical stakeholders alike. From there, we discuss how to fix the problem and how to prevent it in the future.
Invariably, I offer remediation suggestions. Those vary considerably. But what doesn’t vary is my advice for avoiding a backslide. Install your own copy of NDepend and actively keep an eye out for X, Y, and Z.
If you have your own copy of NDepend or another static analyzer, you don’t need to wait for some consultant to come in and tell you that. You can take the free, easy advice from this blog post. Keep the tool around, keep running it, and keep improving.