This is part one of two one the subject of Code Metrics and NDepend. This first one explains why Code Metrics are important, and the second one will give a tour of the latest NDepend version, NDepend v6.
Another project of mine at work is currently developing a pipeline to gather metrics periodically from our (somewhat large) code base. Sounds simple enough, right?
Well, kinda. But that is a story for another day. Today, I want to talk about the .NET user group talk I gave back in March, here in Wellington. The title of the presentation was much the same as this, however this time around, Patrick Smacchia and the lovely people at NDepend have given me a trial copy of NDepend v6 to play with and show off.
Before I begin, I just want to thank Patrick Smacchia for the free copy, both now and back then, as well as Ben Amor from Xero who voluntold me to take part in the .NET user group talk. Also the .NET user group themselves, helmed by Bevan Arps for not chewing me out for my naive methods of development.
Numbers, Numbers everywhere..
I've been in the industry for all of 7 months now, however, what I believed I did back before I started has now drastically changed. You see, when I started, a bleary eyed second year student, I believed that I would be paid for one thing:
I get paid to write code.
Which is sensible, right? I'll be sitting at the computer, eight hours a day developing whatever my bosses deem necessary. However, over the following three months, something became more apparent. I think Coda Hale, a then Software Architect for Yammer.com, put quite well in a talk he gave back in 2011:
I get paid because I generate business value.
As I mentioned previously, there are 1001 different ways to do anything in programming, therefore in order for the business people to keep happy, we obviously need to provide some form of value for what we do. Therefore:
Code → Business Value
As in, the code I write will create business value, but not as its written, only when it is run. No body cares if I can write 100,000 lines of code, it's all down to if it does what it is meant to, and we can only know this if we run it.
By this logic, therefore, good code drives better business value, right? But how do I write better code? How do I know that I've written good code?
Welcome to the million dollar question for every developer ever.
Hale talks then about our Mental Model. When developers write code, they generally receive a problem, then immediately start modelling the solution in their head. The more you write code, the more it leaks out into the real world - In my daily wake up, I allot x amount of time to do y, in order to make it to z. Generally it works out, but 9/10 my boy-ish traits come through and just lie in bed for that extra 20mins, throwing everything out of wack.
However, back to the developer and the model. Take this code for instance:
You can see on the comments, should we choose the LINQ evaluation, or the foreach loop on the line below to sum ages? Since we are fans of performance and clean code, we'd choose the second one, as although LINQ introduces a little bit of overhead, its negligible in this context. This is our mental model talking - we know what both do, and we will take an instinctive and educated guess at what will happen when we plug our values into the methods?
Well, too bad for us, some fool has thrown a Thread.sleep in the ForEach override, and overally, this method is much slower for us:
But it doesn't matter, Age.Add doesn't even work:
Believe me, this is a constant struggle for Developers and Software Engineers, that if we were able to write our own University slogan, it'd go something like this:
So long story short, sometimes our mental model sucks. What we perceive as good in our mind could suck in the real world. Most developers feel this when they look at their code they wrote just that morning.
What does this mean, then?
Knowing your code matters.
- If I know how my code runs, I can write better code.
- Better code generates more business value
- More business value means the boss will keep me around ($$$)
But how do we do this?
To Understand your Code, you should Measure it.
Numbers, dare I say it, make everything easier. For example, if I was to apply to a job, and just provide my skills, at a quick look it may look favourable:
All well and good right? Well, not really.
As soon as you add the numbers to something, it becomes apparent I only have a little experience, or in the case of SQL, I have no experience. Measuring something instantly gives us an idea of what we have on our hands.
Lets apply this to a programming situation - Everyone's favourite game, Find the Bottleneck. Your manager has come to you, and said the following line.
You know for a fact that the bug can be occurring in one of four places: Content, your WebAPI, the Service Library, or in one of the Third Party Assemblies. We could just go slowly, piece by piece through each of the levels of your system, and depending on its size, could take days, if not weeks.
But, your team was smart, and put metrics monitors through the code:
Instantly, we can see where our problem lies, and therefore can isolate the issue much more quickly.
The code runs, it generates business value, we get paid. Job done.
However, what about someone elses code?
Developer Turnover, and Code Quality
So, after isolating the problem in your code, you find it to be in VeryImportantClass.cs, written by a guy called Jerry a couple years back, and over time, has been incrementally added on over time to be:
- 4203 lines long
- 6 Levels deep in Inheritance
- 24 Methods in total, two of which contain 17 parameters
- Total Cyclomatic Complexity of 120
- Two methods look the same, except one accepts a String as a parameter, the other an Integer.
- Cannot be instantiated.
This brings in the idea of Code Quality - Good Code, Bad Code coming into play again. However, many of us would balk at the idea of untangling the mess that is VeryImportantClass, and therefore, if not forced to, VeryImportantClass will continue to be a pain to developers.
Good Code is better for Developers.
So how do you make sure that your code is kept clean? Technical Debt is unavoidable, however there are methods you can take that will ensure to keep it clean - Code Analysis.
There are two main avenues of Code Analysis available, static and dynamic - they're pretty self explanatory terms:
- Static analysis is good as it exposes problems that may exist in the future, and is really code at exploring every execution paths. (Static Analysis Tools, Mathematics (Finally, all that work on loop invariants comes in handy!))
- Dynamic Analysis, however, is very good at exposing problems too complex for static analysis to find, and is good for discovering security issues, and debugging. (Timers, System Resources, Code Coverage (Tests))
Although dynamic analysis is just as important, in the today I'll only deal with Static Analysis, as its the more interesting to show off, and also easier, as I don't readily have a code base available to show you.
There are a number of tools and metrics you can watch over time (Lines of Code (kinda), Cyclomatic Complexity, Code Coverage), and a number of tools at your disposal (NDepend, FxCop (discontinued), Visual Studio, NCrunch/dotCover (Code Coverage), and Roslyn). Perhaps one of the most powerful tools in .NET is NDepend, and that is what we're going to delve into today.
Now that all the back-story is behind us, we can make like Lord of the Rings, and split this into two. Rather than fill this page up and overwhelm it with more jargon, I'll split the NDepend tour into its own post. You can find that HERE.
As always, you can find me on Twitter, @rack_jobinson, but generally an email is the best port of call: jackrob1994 - at - gmail - dot - com. I also have my github, which is currently full of University assignments, and little musings, and I hope to slowly add to it in the coming months, unlike this blog :P