Software metrics can provide useful insights into code quality and complexity. Code metrics like lines of code, cyclomatic complexity, and weighted method count measure characteristics like code size, logic complexity, and class complexity. Design metrics evaluate qualities like coupling and cohesion. Metrics are most effective when used to identify improvement opportunities rather than to judge the overall quality of code or designs. Calculating and tracking metrics over time can help optimize code and catch regressions during development.
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
PHP Benelux 2012: Magic behind the numbers. Software metrics in practice
1. Magic behind the
numbers
Software metrics in
practice
Sebastian Marek, Software Architect
2. @proofek
• a Pole living in Sheffield
• over 10 years PHP
experience
• co-author of 2 PHP books
• big fan of process
automation
• TDD and CI
• occasionally contributes
to open source projects
• wants to be a knight
3. Agenda
What I will be talking about
• Code metrics
• Design metrics
What I will not be talking about
• Project metrics
https://joind.in/4758
6. What is a metric?
“It is the mapping of a particular
characteristic of a measured entity to
a numerical value”
Source: Object-Oriented Metrics in Practice
7. Software design
“Good design quality metrics are not
necessarily indicative of good designs.
Likewise, bad design quality metrics
are not necessarily indicative of bad
designs”
Source: Jdepend Docs
8. System maintenance
• Obsolete documentation
• Convoluted design
• Intensive patch mechanism (hacking)
• Large size
• Severe duplication
• Obsolete parts (dead code)
• Long build times
• Loss of original developers
9. Simple metrics
• CLOC – comment lines of code
• ELOC – executable lines of code
• LOC – lines of code
• NCLOC – non comment lines of code
• NOP – number of packages
• NOC – number of classes
• NOM – number of methods
10. Cyclomatic Complexity (CYCLO)
Cyclomatic complexity measures the
amount of decision logic in a single software
module.
24. JAVA
Metric Low Avg High V.High
CYCLO/Line of code 0.16 0.20 0.24 0.36
LOC/Method 7 10 13 19.5
NOM/Class 4 7 10 15
Source: Object-Oriented Metrics in Practice (based on 45 Java projects)
25. C++
Metric Low Avg High V.High
CYCLO/Line of code 0.20 0.25 0.30 0.45
LOC/Method 5 10 16 24
NOM/Class 4 9 15 22.5
Source: Object-Oriented Metrics in Practice (based on 37 C++ projects)
26. WMC and AMW
Weighted Method Count – total complexity of a class
Average Method Weight – average complexity of a method
27. JAVA
Metric Low Avg High V.High
WMC 5 14 31 47
AMW 1.1 2.0 3.1 4.7
LOC/Class 28 70 130 195
Source: Object-Oriented Metrics in Practice (based on 45 Java projects)
28. C++
Metric Low Avg High V.High
WMC 4 23 72 108
AMW 1.0 2.5 4.8 7.0
LOC/Class 20 90 240 360
Source: Object-Oriented Metrics in Practice (based on 37 C++ projects)
35. NPATH – acyclic execution path complexity
NPATH is an objective measure of software
complexity related to the ease with which
software can be comprehensively tested
Edgar H. Sibley
36. NPATH – acyclic execution path complexity
expressions Number of && and || operators in expression
if NP(<if-range>)+NP(<expr>)+1
if-else NP(<if-range>)+NP(<else-range>)+NP(<expr>)
while NP(<while-range>)+NP(<expr>)+1
for NP(<for-range>)+NP(<expr1>)+NP(<expr2>)+
NP(<expr3>)+1
break 1
continue 1
return 1
sequential 1
function call 1
37. NPATH – example
class Foo {
public function example() {
if ($a == $b) {
if ($a1 == $b1) {
fiddle();
} else {
fiddle();
}
}
if ($e == $f && $g == $z) {
for ($n = 0; $n < $h; $n++) {
fiddle();
}
}
return true;
}
}
38. NPATH – example
class Foo {
public function example() {
if ($a == $b) {
if ($a1 == $b1) {
fiddle(); 1
} else {
fiddle();
}
}
if ($e == $f && $g == $z) {
for ($n = 0; $n < $h; $n++) {
fiddle();
}
}
return true;
}
}
39. NPATH – example
class Foo {
public function example() {
if ($a == $b) {
if ($a1 == $b1) {
fiddle(); 1
} else {
fiddle(); 2
}
}
if ($e == $f && $g == $z) {
for ($n = 0; $n < $h; $n++) {
fiddle();
}
}
return true;
}
}
40. NPATH – example
class Foo {
public function example() {
if ($a == $b) {
if ($a1 == $b1) { 2
fiddle(); 1
} else {
fiddle(); 2
}
}
if ($e == $f && $g == $z) {
for ($n = 0; $n < $h; $n++) {
fiddle();
}
}
return true;
}
}
41. NPATH – example
class Foo {
public function example() {
if ($a == $b) {
if ($a1 == $b1) {
fiddle();
} else { 2
fiddle();
}
}
if ($e == $f && $g == $z) {
for ($n = 0; $n < $h; $n++) {
fiddle();
}
}
return true;
}
}
42. NPATH – example
class Foo {
public function example() {
if ($a == $b) {
if ($a1 == $b1) {
fiddle();
} else { 2
fiddle();
}
}
if ($e == $f && $g == $z) {
for ($n = 0; $n < $h; $n++) {
fiddle();
}
}
return true;
}
}
43. NPATH – example
class Foo {
public function example() {
if ($a == $b) { 2
if ($a1 == $b1) {
fiddle();
} else { 2
fiddle();
}
}
if ($e == $f && $g == $z) {
for ($n = 0; $n < $h; $n++) {
fiddle();
}
}
return true;
}
}
44. NPATH – example
class Foo {
public function example() {
if ($a == $b) { 2
if ($a1 == $b1) {
fiddle();
} else { 2
fiddle();
}
} 3
if ($e == $f && $g == $z) {
for ($n = 0; $n < $h; $n++) {
fiddle();
}
}
return true;
}
}
45. NPATH – example
class Foo {
public function example() {
if ($a == $b) {
if ($a1 == $b1) {
fiddle();
} else { 3
fiddle();
}
}
if ($e == $f && $g == $z) {
for ($n = 0; $n < $h; $n++) {
fiddle();
}
}
return true;
}
}
46. NPATH – example
class Foo {
public function example() {
if ($a == $b) {
if ($a1 == $b1) {
fiddle();
} else { 3
fiddle();
}
}
if ($e == $f && $g == $z) {
for ($n = 0; $n < $h; $n++) {
fiddle(); 1
}
}
return true;
}
}
47. NPATH – example
class Foo {
public function example() {
if ($a == $b) {
if ($a1 == $b1) {
fiddle();
} else { 3
fiddle();
}
}
if ($e == $f && $g == $z) {
for ($n = 0; $n < $h; $n++) { 1
fiddle(); 1
}
}
return true;
}
}
48. NPATH – example
class Foo {
public function example() {
if ($a == $b) {
if ($a1 == $b1) {
fiddle();
} else { 3
fiddle();
}
}
if ($e == $f && $g == $z) {
for ($n = 0; $n < $h; $n++) { 1
fiddle(); 1
} 2
}
return true;
}
}
49. NPATH – example
class Foo {
public function example() {
if ($a == $b) {
if ($a1 == $b1) {
fiddle();
} else { 3
fiddle();
}
}
if ($e == $f && $g == $z) {
for ($n = 0; $n < $h; $n++) {
fiddle(); 2
}
}
return true;
}
}
50. NPATH – example
class Foo {
public function example() {
if ($a == $b) {
if ($a1 == $b1) {
fiddle();
} else { 3
fiddle();
}
}
if ($e == $f && $g == $z) {
for ($n = 0; $n < $h; $n++) {
fiddle(); 2
}
}
return true;
}
}
51. NPATH – example
class Foo {
public function example() {
if ($a == $b) {
if ($a1 == $b1) {
fiddle();
} else { 3
fiddle();
}
}
if ($e == $f && $g == $z) { 3
for ($n = 0; $n < $h; $n++) {
fiddle(); 2
}
}
return true;
}
}
52. NPATH – example
class Foo {
public function example() {
if ($a == $b) {
if ($a1 == $b1) {
fiddle();
} else { 3
fiddle();
}
}
if ($e == $f && $g == $z) { 3
for ($n = 0; $n < $h; $n++) {
fiddle(); 2
}
} 4
return true;
}
}
53. NPATH – example
class Foo {
public function example() {
if ($a == $b) {
if ($a1 == $b1) {
fiddle();
} else { 3
fiddle();
}
}
if ($e == $f && $g == $z) {
for ($n = 0; $n < $h; $n++) {
fiddle(); 4
}
}
return true;
}
}
54. NPATH – example
class Foo {
public function example() {
if ($a == $b) {
if ($a1 == $b1) {
fiddle();
} else { 3
fiddle();
}
}
if ($e == $f && $g == $z) {
for ($n = 0; $n < $h; $n++) {
fiddle(); 4
}
}
return true; 1
}
}
55. NPATH – example
class Foo {
public function example() {
if ($a == $b) {
if ($a1 == $b1) {
fiddle();
} else {
fiddle();
}
}
12
if ($e == $f && $g == $z) {
for ($n = 0; $n < $h; $n++) {
fiddle();
}
}
return true;
}
}
71. Summary
“We believe that software metrics, in general, are just tools. No
single metric can tell the whole story; it’s just one more data
point. “
“Metrics are meant to be used by developers, not the other way
around – the metric should work for you, you should not have
to work for the metric. “
“Metrics should never be an end unto themselves. Metrics are
meant to help you think, not to do the thinking for you.”
Alberto Savoia
72. Resources
• PHP Depend - http://pdepend.org/
• PHP Mess Detector - http://phpmd.org/
• Manuel’s home page - http://manuel-pichler.de/
• PHPUnit - http://www.phpunit.de/
• phploc - http://sebastianbergmann.github.com/phploc/
• Sonar - http://www.sonarsource.org/
• “Object-Oriented Metrics in Practice” by Michele Lanza
and Radu Marinescu (ISBN 978-3540244295)