How to Know When Code is Complex, Part 3: Using the McCabe Complexity Metric
The McCabe Complexity Metric, as discussed in my last post, relates to the number of decision points (points where the logic path splits) in a section of code. When used along with the Halstead Metric, the McCabe Metric can help you objectively assess and compare the complexity of new programs and applications. By using a threshold you can focus on the areas of greatest complexity, which you can then break into smaller, more manageable, logical sections.
But how can you put the McCabe Complexity Metric to use?
Recall it works something like this: If we had 4 statements which moved data from one field to another and there are no decisions it, that section would get a score of 1. If we put in one decision then there would be two paths and it would be scored as 2. If one of the branches has a decision then there would be three paths, it would get a score of 3, and so on. This continues until you end up with, at times, pretty big numbers. Generally it’s best to keep each section of code at 10 or less. The higher the number – and I’ve seen it be in the thousands – the harder it will be to understand and implement a change for a section of code.
Making a practice of assigning a McCabe score, in combination with noting how long it takes to understand each program’s code, helps developers predict how long it will take to implement changes on projects with similar McCabe scores. For example, they could say to an end-user, “this change is in a block of code that has over 500 paths, but the last one we did for you had only 20. It will take X amount of time longer to assess, change and test.” It can also be useful assigning resources to the project. Managers may want to use more experienced staff on areas with the highest complexity and task them with not only implementing the change, but also simplifying the code, if possible.
Extending the McCabe Metric further in combination with the Halstead Metrics, you can compare applications in your portfolio. For example, the metrics can help you choose whether to acquire a new application or consolidate multiple applications into one. To make this determination, you would want to look at the functionality and the complexity as you will need to support it in the future. There are many things you can do with this metric to help in this regard. One is to use a threshold and record how many sections are above the threshold. Another is to calculate an average for the program to aid in comparisons.
The McCabe Complexity Metric is also helpful in determining the minimum number of unique test cases needed to test the code. So, if we had a section that had a score of 57, we would know that at the very least 57 test cases are necessary to fully test the code. But it is the unique test cases, just 57 records running through it may not work, but you know that 20 definitely won’t work. Using the McCabe Complexity along with a Control Flow diagram you will be able to quickly come up with the necessary test cases. The number then establishes a baseline for complete testing. This, along with code coverage results, can provide valuable proof of your testing efforts.
Let me close with a last example of its use. Once I was consulting with an organization on a project to increase the overall quality of their code. They did a before/after comparison of a program before moving the changes to production. The Halstead numbers had gone up slightly, but reviewing the McCabe numbers revealed a big change that could have future consequences. Originally most of the program had low scores, but there were two areas which had numbers over 300. In the new version there was one area with over 800 with the rest was below 100. So, the complexity was now clustered into one area which would be extremely difficult to understand, change, and test in the future. They sent it back for rework to make sure the complexity scores were reduced. Had they not had this practice in place, the code would have been moved to production, and at some point in the future, it would have caused difficulties in maintenance. Resolving it now, with the changes fresh in mind, should be easier than dealing with it later. Over time using both the Halstead and McCabe metrics you will gain valuable, objective measures for complexity so you can halt – and perhaps reverse – the trend of increasingly more complex programs.
Image attribution: robson
Latest posts by Mark Schettenhelm (see all)
- Planning Better for Failure: How Mainframe Error Messages Impact CX - December 12, 2017
- What Makes ISPF So Scary? Five Reasons to Banish the ‘Green Screen’ - October 31, 2017
- Ten Cross-platform and Mainframe DevOps Tools You Need Today - August 7, 2017