As the name suggests, code complexity measures how complex is your code. If you consider the number of possible paths your code produces, the measure is called cyclomatic. If you want other angle to measure the complexity, such as how difficult is to be read by a human, we call it cognitive.
Why is this measure important
If we take the following code
1 2 3 4 5 6 7 8 9 10 |
public int crazySum(int x, int y) { int sum = 0; if(x > y) { sum = x + y; } if(y > x) { sum = y; } return sum; } |
a graph like this one can be produced
From this graph we can deduce the number os possible paths an application can follow during its execution M=6-5+2x1
, or 3. (Check the formulas below)
If you develop unit tests, you easily reach the conclusion that exists a strong correlation between the number of possible paths and the number of unit tests necessary to reach a coverage of 100% of the code!
Now, if your method, is too complex, or/and has a lot of possible paths of execution, you will need to develop and maintain a lot of unit tests, and, for sure, difficult for another person to understand and continue your work.
You want to have a low value for this metric. Usually, Sonar proposes a maximum value of 15. For any value above this one, you should consider refactoring your code.
By the way, the recommended value is 4 or 5.
Cyclomatic complexity
This measures how difficult is your code to be tested.
If you consider a graph generated from code, you can use the formula
E -> the number of edges in the graph
N -> the number of nodes in the graph
P -> the number of connected components (a method is considered a component, so in these cases P = 1)
For Java like languages another way to calculate exists
- assign one point for the start of the method
- Add one point for each conditional statement, such as an
if
- Add one point for each iterative statement
- Add one point for each
case
ordefault
in aswitch
- Add one point for each Boolean condition
&&
,||
- Sometimes it is added one point for each
throws
,throw
,catch
, andfinally
blocks, but it is advised to not use these points since Java has a very verbose code regarding exceptions
Cognitive complexity
This measures how difficult is your code to be read and understood.
There isn’t a specific formula to apply, but usually what is done is to take the regular formula for the Cyclomatic complexity and take into consideration how hard is to assess mentally the code
- add points for
catch
,switch
- Ignores the number of Boolean operator in an
if
, because mentally the effort is the same to reada && b
and thea && b && c
- Add points for each recursion (the Cyclomatic ignores this)
- Increments for nested flows-break structures
Tools to measure the complexity
These are the ones I use most
Google for complexity metrics and several plugins for several languages and IDEs will be displayed.