Kent Beck opened the Startup Lessons Learned Conference earlier today with an excellent presentation about how lean startup thinking has caused him to rethink the agile manifesto.
If you are reading this on Friday April 23rd you may want to stop and go watch to one of the live streams of the conference. You can come back here later to read these tidbits from Kent’s speech.
Items in italics are my own editorial…
Kent opened his speech by discussing how lean startup thinking has caused him to realize that the typical Build -> Measure -> Learn (then back to Build) cycle is backwards and in fact should be Learn -> Measure -> Build until you have a deep understanding of what the market wants and needs. You will know when you understand the markets wants and needs when people are beating down your door for what you are offering.
Individuals and interactions over processes and tools
Working software over comprehensive documentation
Customer collaboration over contract negotiation
Responding to change over following a plan
The items on the left are generally improvements over those on the right, but lean startup thinking teaches us that they are sub-optimal before we know what is needed. When “the learning you need is learning about needs” the following principles trump the the items on the left and the right:
Team vision and discipline
Validated learning
Customer discovery
Initiating change
A subject that we will spend a lot of time discussing on this blog is how context and values affect the metrics you should be gathering. Being in the learning about needs phase is a very special time in a products lifecycle that requires quite different thinking. The lean startup movement has a great perspective on what that thinking should be.
When designing a metrics program you need to understand what your primary problem is. Is it building the right thing or building the thing right? If you don’t know what the market needs. (I don’t mean think you know. I mean know!) Then you should optimize for learning. It would be wasteful to spend effort on great engineering to create the wrong product.
Once you do know what the market needs then you can start thinking about metrics that tell you how well built your product is. This is when The First Four come in.
I highly recommend watching Kent’s talk if you can find it. I’ll add a link here when I find one.
In this video Enerjy Software asks several well known software development speakers, authors and bloggers what they think about Cyclomatic (McCabe) Complexity.
If Java-Metrics.com is going to live up to its tagline “Everything you ever wanted to know about Java metrics…” I’m going to need to point you to a broader set of resources than I can cover in depth.
I scan about 1500 blogs daily for items of interest. (NetNewsWire, Instapaper and Google Reader rock!) When I find anything readers of Java-Metrics.com need to know I’ll tweet it as @JavaMetrics.
Follow @JavaMetrics on Twitter and get the best news and information as quickly as I uncover it!
Cyclomatic complexity (also known as CCN, v(G), or McCabe complexity) is a big complicated sounding name for a pretty simple metric. In fact, it is so simple that I’m going to give you several definitions. That way you can decide how smart you want to sound when explaining it to other people I’ll also talk about why you should care about CCN and give you a few examples so that you can begin to get a feel for what various cyclomatic complexity numbers translate to in reality.
Don’t think that just because cyclomatic complexity is simple that it isn’t incredibly useful. Out of all the metrics I’ve used over the last 30 years of developing software and advising Fortune 500 companies how to build better software, cyclomatic complexity is one of The First Four metrics I advise people start with.
If I were to explain cyclomatic complexity to a normal person I would just tell them that it is the number of decisions in a piece of code. I might even call it McCabe complexity so it doesn’t sound as scary.
When I want to sound smart, I explain CCN as the number of linearly independent paths through the flow graph of a method. A tester might think of this as the minimum number of tests needed to verify the entire function. In fact, cyclomatic complexity was invented when Thomas McCabe was working to create a formula to determine the minimum number of tests needed for a piece of code.
Finally, if I’m talking to a math geek I would say you calculate v(G) of a function by taking the function’s control flow graph and subtracting the number of vertices it has from the number of edges and then adding 2. Now you may be able to guess where the name v(G) comes from.
Why Should I Care About Cyclomatic Complexity
Regardless of how you describe cyclomatic complexity, one thing is always the same. Lower numbers are better.
Higher numbers mean more to go wrong, more to test, and a higher probability that a developer reading or changing the code will miss something. All of these lead to more bugs and slower development in code with a higher CCN. If you are really impatient (or you just enjoy reading technical documents written for government agencies) you can read NIST Special Publication 500-235 – Structured Testing: A Testing Methodology Using the Cyclomatic Complexity Metric for proof of this. For those of you without such a high tolerance for pain I’ll cover the important bits of the report on this blog.
Examples of Cyclomatic Complexity
We will start by looking at a few increasingly complex versions of the classic Hello World program written in Java.
In the first version the main method has a cyclomatic complexity of 1 because there are no conditionals or loops in the code.
This next version checks to see if you passed an argument to the main method and prints a different message if you did. This version has a cyclomatic complexity of 2 because of the single if statement in the method.
Our final version of Hello World has an if and an else if statement, raising the cyclomatic complexity to 3.
publicclass Hello {publicstaticvoid main(String[] args){if(args.length==0){System.out.println("Hello, World!");}elseif(args.length==1){System.out.println("Hello, "+ args[0]+"!");}else{System.out.println("Aargh, too many people to say hello to!");}}}
Those are all pretty simple. Why don’t we move on to some real world code and have some fun by airing a bit of my dirty laundry. Here is the most complicated method in Panopticode an open source project I wrote some years back. This method has a cyclomatic complexity of 11. Any method with that high of a CCN is worth looking at very carefully to see if it can be simplified.
Ugh. I’m sorry you had to see that. Whenever I write something that complex I make doubly sure it is well unit tested.
How High Is Too High?
As that last method shows once we get up around a cyclomatic complexity of 10 the code gets pretty ugly. On my own projects I review any method with a CCN of 5 or higher and if I find anything with a cyclomatic complexity of 10 or higher that I don’t know how to simplify I ask for help cleaning up the code.
According to the NIST report I mentioned earlier various projects reported that a high CCN, with high being somewhere between 9 and 12, is strongly correlated with significantly increased defects. Looking at the method with a CCN of 11 should make it intuitively clear why that is the case.
Coming Up…
The next post in this series will show you how to gather and report on cyclomatic complexity. Later on we will see the problems with rolling cyclomatic complexity up to a class, package, or project level and how Panopticode addresses those problems.
If you want to get ahead of the class you can check out the JavaNCSS project and get started looking at the CCN of some of your own code.
Please let me know in the comments below what your thoughts on this post are. Did you find it helpful? Is there anything I can make clearer? Have you used your new found knowledge to start the next Facebook/Google/Apple?
The First Four are the metrics I advise every Java metrics process begins with. They are fast and easy to collect and will immediately benefit your project by reducing the likelihood of defects and improving productivity. We had a snafu last week here at HQ and lost the drive that had all of the fancy [...]
Java Metrics will launch in early April. We will be covering the full spectrum of topics around Java metrics including techniques for deciding what metrics to gather, how to interpret metrics such as cyclomatic complexity, duplicate code, code coverage, and Java coding standards violations and how to refine your metrics, automating metrics collection, when to [...]