There are two actions you can take to mitigate the CC.
1. unittesting-- determine the number of test cases required to detrmine all the paths. Apply common sense risk/reward strategy to minimise the number of real test cases required to cover all the paths.
2. refactoring -- unit testing only helps with mitigating risk, so reduce the complexity of your code, refactor it after having written your unit tests so that you can confidently refactor your code to make it less complex, without breaking anything.
It means, how complex your class is. Every decision point in a method (if, while, for, case) in a method is calculated and 1 is added for a method'd entry point. So if a method has lot of decision points, then it is considered to be complex. for example
the above simple method has a Cyclomatic Complexity of 2 (if, else) + 1(method entry point) = 3
so the above method is simple. if you have a CC of say 25, then try and refactor it, to make it simple to understand and maintain.
Well, I really don't know much about this, but my understanding is that cyclomatic complexity is a metric primarily for procedural code, and applies to OOP only at the method level. So I wouldn't expect that moving methods among classes would lower the cyclomatic complexity value.
Instead, I think you want to focus on streamlining the control flow by reducing the number of decision points (and thus possible paths) in the logic.
Not all code with high cyclomatic complexity is complex. A switch statement is a perfect example. A switch statement will give a high cyclomatic complexity without being really complex.
Also, this code will give a cyclomatic complexity of 11
and this code will give the same cyclomatic complexity
Clearly one is more complex than the other even though the cyclomatic complexity is the same
So, first of all, you should take cyclomatic complexity with a grain of salt. It is wise to strive for low cyclomatic complexity, but it should be used as a tool to seek out badly written code. Reduction of cyclomatic complexity should not be a goal, by itself.
Having said that, the best way to reduce cycolmatic complexity is to , well, make your code less complex. Just moving methods around without changing them won't help because you are not reducing the cyclomatic complexity of the functions. You can start off by looking at your code and seeing where you can break it off into differrent functions. You can identify places where you can make reusable functions. [ March 23, 2006: Message edited by: Jayesh Lalwani ]
Here some steps to tacke the issue of high Cyclomatic Complexity Number(CCN):
* Generalize the code/methods * Read Martin Fowlers' Refactoring book -- this contains lots of ideas * Most of the developers has an idea/concept that adding more methods will reduce the performance and write big methods with lots of if/else, indentation,etc --which finally leads to high CCN. But performance wise, most of the performant code is concetrated only in 20% of whole code base(80-20 rule).So one has to see, is this method(that is having high CCN) is really performance critical code-path. If not,then break that method to small methods to generalize.
* Introduce the checks in organization's build process to STOP inserting the code with high CCN in to production loads( this process may have some exception cases for old code and new code based on need/etc. But these exceptions need to be ratified by discussion). * Use Checkstyle in ANT build files to give feedback/warning on CCN numbers * Use Checkstyle in ANT build files to give feedback/warning on large method NCSL(non commented source lines) * Use Checkstyle in ANT build files to give feedback/warning on deep indentation in code base * Educate the Developers about CCN. Let them know/use JavaNCSS package for getting the CCN numbers * Educate the Developers about OOP(for new/old/extension design/coding) for reusability am=nd maintainable code * Educate the Developers about the Refactoring(Martin Fowlers book read is a MUST). Also let them use Eclipse/other-famous-IDE's refactoring tools for reducing the CCN/etc
In my experience, a high CC for a class in an OO language typically means one of two things:
- The class is taking up more than one responsibility, thereby violating the Single Responsibility Principle. The response is to split the class into smaller, more cohesive classes.
- There is a lot of conditional logic in the class. Often that is a sign of a rather procedural programming style - of not making use of much polymorphism. Often introducing a pattern like Command or Strategy can reduce not only the metrics value, but also the actual complexity (at least in my eyes ).
Do you have example code that we could discuss?
The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus