Cyclomatic And NPath Complexity Explained
When software developers use PHP Mess Detector, they may likely encounter two sophisticated terms, namely, cyclomatic complexity and NPath complexity, which they may initially find daunting. However, with cyclomatic and NPath complexity explained in a straightforward way, there’s no need to be overwhelmed by them.
That confident assurance comes from Niklas Modess, a Stockholm-based PHP developer and consultant and the author of the eBook “Deploying PHP Applications” (2020).
PHP Mess Detector (PHPMD), by the way, is PHP Depend’s (a static code analysis program) “spin-off project,” according to the PHPMD website. Its objective is to be like PMD.
Going back to cyclomatic complexity and NPath complexity, Modess describes them as “fancy words for quite simple concepts.” He also adds that each term “sounds really scary” for some.
Nonetheless, Modess assures that with cyclomatic and NPath complexity explained in the simplest way possible, software developers like him will no longer be intimidated by them.
Niklas Modess says that cyclomatic and NPath complexity play an important role when writing testable code and maintainable code.
When doing static code analysis, developers use cyclomatic and NPath complexity. These two concepts help developers to assess or gauge the complexity of a certain function.
Cyclomatic complexity is an easy and simple concept, according to Modess, and what it essentially does is to “count some statements.”
Ten points happen to be the normal threshold for cyclomatic complexity. Aim to make it lower if the complexion of the function turns out to be greater than 10.
This will start with 1 point being added for the function declaration. Then what follows next is that for every “case,” “for,” “if,” and “while,” 1 point will be added as well.
A cyclomatic complexity of 12 becomes the result of this function, and to show it, please check the image below.
The image above shows an example code taken by Modess from a documentation by PHPMD.
When it comes to this one, Modess admits that NPath complexity can be “a bit trickier” than cyclomatic complexity, pointing to a bad PHPMD documentation.
According to PHPMD, as quoted by Modess from its website: “The NPath complexity of a method is the number of acyclic execution paths through that method.”
Upon reading that for the first time, Modess confessed that such an explanation made no sense at all for him. “Zero,” as he bluntly put it. He reiterated what he stressed out earlier: that these are just simple concepts presented using “fancy words.”
For Modess, a simple explanation for NPath complexity is to just say that it’s about “how many ‘paths’ there are in the flow of your code in the function.”
Below is an image that illustrates an example function written by Modess.
Based on the image above, 4 is the function NPath complexity. Why? It’s because the function has 4 probable outcomes, as there are 2 statements, and each of these two statements shows 2 probable outcomes (2 * 2 = 4).
There will be a complexity of 8 if one more statement that has 2 probable outcomes gets added (2 * 2 * 2 = 8).
Modess said that NPath complexity could swiftly become unmanageable. One might be surprised to discover functions with complexity greater than 100,000 in legacy code. An NPATH complexity threshold has a default value of 200. To reduce complexity, try to maintain a value lower than 200.
Importance of Complexity
Between simple code and complex code, the former will always be better, according to Modess. When it comes to testability, readability, and maintainability, he said that simple code should be used.
For instance, a unit test needs to be written. The function has an NPath complexity of 18.
What does that one mean?
If you desire a “100% code coverage,” said Modess, then an NPath complexity of 18 means 18 probable outcomes that you need to test. Such could lead to “pretty messy tests,” he warned.
Why is that so?
Modess explained that when writing tests, one naturally intends “as much isolation as possible.” It’s the main reason why, in one’s application, one should strive to constantly lessen the complexity.
Now with cyclomatic and NPath complexity explained, Modess hoped that these two concepts would not anymore overwhelm software developers.
In his eponymous blog, business strategist and technologist Brandon Savage describes cyclomatic complexity as “a simple measure of complexity in an application or routine.”
According to him, for the reason that there should always be one code path in any case, cyclomatic complexity therefore should never be lower than 1.
With cyclomatic and NPath complexity explained already by Modess, Savage also offered his views about them.
Savage, who is also the author of the eBooks “Mastering Object Oriented PHP” (2013) and “Practical Design Patterns in PHP” (2014), stated that the acceptable cyclomatic complexity “for most routines,” are the following:
(1) below 4 – “good”
(2) between 5 and 7 – “medium complexity”
(3) between 8 and 10 – “high complexity”
(4) above 10 – “extreme complexity”
As for NPath complexity, in his personal opinion, Savage said that code refactoring is needed for an NPath complexity greater than 140 in order to reduce complexity.
Boston-based software company Axelerant recommends a couple of steps to reduce cyclomatic and the NPath complexity:
(1) “Use small methods.”
(2) “Reduce if/else statements.”
To lower the NPATH value, Checkstyle (a development tool for programmers), in its website, suggests these two methods:
(1) distribute functionality
(2) employ several “if statements as a switch statement”
With cyclomatic and NPath complexity explained in a simple way by a professional expert, one should have now realized where higher numbers will lead them to.
As what Perforce, a Minneapolis-based software company, underscores on its website: “Lower Cyclomatic Complexity = Better Code.”
It’s hard to test a code with a complexity greater than what is acceptable, which also means more chances of making mistakes. Therefore, lower numbers, good; higher numbers, bad.
It can be said that with cyclomatic and NPath complexity explained, the importance of reducing complexity should now be clear.