Measuring Maintainability
Dennis de Greef
Dennis de Greef
Software Developer at TransIP
Meetup addict
Tech enthousiast
Occasional speaker Bass player
Domotica Software architect Hardware hacker
Infrastructure engineer
Talk roadmap
- About static software analysis
- Measuring lines of code
- Measuring complexity
- Measuring coupling
About software statistics
Measuring Lines of Code
How many lines of code?
1 <?php
2
3 /* this is a for-loop */
4 for ($i = 0; $i < 100; $i++)
5 {
6 printf("hello");
7 }
How many lines of code?
1 <?php
2
3 /**
4 * This is a for-loop
5 */
6 for ($i = 0; $i < 100; $i++) printf("hello");
Depends on your definition
LOC: Physical lines of code
LLOC: Logical lines of code
CLOC: Comment lines of code
NCLOC: Non-comment lines of code
Different types:
How many lines of code?
7 physical lines of code
3 logical lines of code
1 comment lines of code
6 non-comment lines of code
1 <?php
2
3 /* this is a for-loop */
4 for ($i = 0; $i < 100; $i++)
5 {
6 printf("hello");
7 }
How many lines of code?
6 physical lines of code
3 logical lines of code
3 comment lines of code
3 non-comment lines of code
1 <?php
2
3 /**
4 * This is a for-loop
5 */
6 for ($i = 0; $i < 100; $i++) printf("hello");
Some statistics
LOC

Physical
CLOC

Comment
NCLOC

Non-Comment
LLOC

Logical
symfony-standard 371490
102161

(27.50%)
269329

(72.50%)
84262

(22.68%)
zend-framework2 306097
112498

(36.75%)
193599

(63.25%)
56053

(18.31%)
laravel-framework 78191
35156
(44.96%)
43035

(55.04%)
11970
(15.31%)
cakephp 93455
42454
(45.43%)
51001
(54.57%)
17235
(18.44%)
phploc 2.1.2-17-gb6bfd40
PSR-2
PSR-2
PSR-2
PSR-2
WARNING!
Don’t use these statistics as a form
of measuring quality or productivity!
People will just ‘game’ the system
*applies different codestyle*
Use it to gain more insight
about the application
“Measuring programming progress by lines of code
is like measuring aircraft building progress by weight.”
--Bill Gates
composer require phploc/phploc
$ phploc loc1.php
phploc 2.0.2 by Sebastian Bergmann.	
!
Size	
Lines of Code (LOC) 7	
Comment Lines of Code (CLOC) 1 (14.29%)	
Non-Comment Lines of Code (NCLOC) 6 (85.71%)	
Logical Lines of Code (LLOC) 3 (42.86%)	
Classes 0 (0.00%)	
Average Class Length 0	
Average Method Length 0	
Functions 0 (0.00%)	
Average Function Length 0	
Not in classes or functions 3 (100.00%)
Measuring Complexity
• Cyclomatic Complexity
• N-path Complexity
Complexity and quality are strongly related
Cyclomatic Complexity
“It is a quantitative measure of the number of
linearly independent paths through a program's source code.”
M = E − N + 2P
E = the number of edges of the graph.
N = the number of nodes of the graph.
P = the number of connected components.
http://www.literateprogramming.com/mccabe.pdf
Simply put:
Counting of decision trees:
- function
- for(each)
- while
- if
- case
Cyclomatic Complexity
1 <?php
2
3 function foo($a, $b) {
4 if($a) {
5 if($b) {
6 echo "Hello World";
7 }
8 }
9 }
10
5 edges
4 nodes
1 compound
M = 5 − 4 + 2x1 = 3
M = E − N + 2P
Cyclomatic Complexity
8 edges
7 nodes
1 compound
M = 8 − 7 + 2x1 = 3
M = E − N + 2P
1 <?php
2
3 function foo() {
4 if($a) {
5 echo '1';
6 } else {
7 echo '2';
8 }
9 if($b) {
10 echo '3';
11 } else {
12 echo '4';
13 }
14 }
Cyclomatic Complexity
How many tests do we need?
M = 8 − 7 + 2x1 = 3
Complete branch coverage:
foo(true, false)
foo(false, true)
Code Coverage
1 <?php
2
3 function foo($a, $b) {
4 if($a) {
5 // ...
6 }
7
8 if($b) {
9 // ...
10 }
11 }
12
13 foo(true, false);
14 foo(false, true);
All paths are tested with these two
function calls.
This implies 100% code coverage.
!
Or does it? What about:
foo(false, false)
foo(true, true) ?
Code Coverage
Path coverage:
http://derickrethans.nl/path-branch-coverage.html
Xdebug 2.3.0
PHP_CodeCoverage: not supported
N-path Complexity
“The NPath complexity of a method is the number of
acyclic execution paths through that method.”
“The NPath complexity of a method is the number of
acyclic execution paths through that method.”
N-path Complexity
“The NPath complexity of a method is the number of
acyclic execution paths through that method.”
N-path Complexity
N-path Complexity
Path coverage
M = E − N + 2P
E = the number of edges of the graph.
N = the number of nodes of the graph.
P = the number of connected components.
N-path Complexity
foo(false, false)
foo(true, false)
foo(false, true)
foo(true, true)
Cyclomatic Complexity = 3
N-path Complexity = 4
N-path is exponential
N-path Complexity
foo(false, false)
foo(true, false)
foo(false, true)
foo(true, true)
Cyclomatic Complexity = 3
N-path Complexity = 4
N-path is exponential
Number of unique paths
N-path Complexity
// …
$count['staticMethods'],
$count['methods'] > 0 ? ($count['staticMethods'] / $count['methods']) * 100 : 0,
$count['publicMethods'],
$count['methods'] > 0 ? ($count['publicMethods'] / $count['methods']) * 100 : 0,
$count['nonPublicMethods'],
$count['methods'] > 0 ? ($count['nonPublicMethods'] / $count['methods']) * 100 : 0,
$count['functions'],
$count['namedFunctions'],
$count['functions'] > 0 ? ($count['namedFunctions'] / $count['functions']) * 100 : 0,
// …
N-path Complexity
The method printResult() has an NPath complexity
of 47683715820312500.
The configured NPath complexity threshold is 200.
Measuring Coupling
http://www.codemanship.co.uk/parlezuml/metrics/OO%20Design%20Principles%20&
%20Metrics.pdf
Martin’s Metrics
Measuring Coupling
Coupling between packages
Packages being either a namespace or composer package
Measuring Coupling
Afferent Coupling (Ca):"
Amount of other packages depending on this class (incoming)
!
Efferent Coupling (Ce):"
Amount of dependencies of this class
!
Instability (I):"
Resilience to change, metric between 0 and 1. Where 0 is stable.
I = Ce / (Ce + Ca)
Measuring Coupling
Ca = 2
Ce = 3
I = Ce / (Ce + Ca)
I = 3 / (3+2)
I = 0,6
I = 0,0 = Completely stable
I = 1,0 = Completely unstable
Measuring Coupling
Abstract:"
Either an abstract class or interface
!
Concrete:"
Any class that is neither abstract or final
!
Abstractness (A):"
How abstract a package is, ratio between 0 and 1. Where 0 is concrete.
A = Abstract / (Abstract + Concrete)
Measuring Coupling
PHPMD (PHP Mess Detector)
Can detect (code size rules):
- Cyclomatic complexity
- N-path complexity
- Excessive method length
- Too many methods
- etcetera
10
200
100
10
And other things
- Clean Code
- Design Rules
- Naming Rules
- Unused Code Rules
Integrating it all
http://jenkins-php.org/
Questions?
Thank youBig thanks to:
!
Derick Rethans (Xdebug)
Sebastian Bergmann"
(PHPLOC, PHPunit,
PHP_CodeCoverage)
Thomas J. McCabe Sr:
Cyclomatic Complexity
Robert C. Martin: Lots of things!

(nicknamed ‘Uncle Bob’)
!
Many more…
Twitter: @dennisdegreef
Blog: dennisdegreef.net
IRC (Freenode): link0
Github: dennisdegreef / link0
PHPNL-Slack: link0
Joind.in: https://joind.in/14991

Measuring maintainability; software metrics explained