Magic behind the
                            numbers

                       Software metrics in
                            practice



Sebastian Marek, Software Architect
@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
Agenda

What I will be talking about
•  Code metrics
•  Design metrics

What I will not be talking about
•  Project metrics



                https://joind.in/4758
Most effective code quality measure
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
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
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
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
Cyclomatic Complexity (CYCLO)




   Cyclomatic complexity measures the
amount of decision logic in a single software
                 module.
Cyclomatic Complexity Number (CCN)

Conditional statements:
•  ?
•  case
•  elseif
•  for
•  foreach
•  if
•  while
CCN2

Conditional statements:
•  ?                         •    &&
•  case                      •    ||
•  elseif                    •    or
•  for                       •    and
•  foreach                   •    xor
•  if
•  while
Cyclomatic complexity

Conditional statements:
•  ?                      •    &&
•  case                   •    ||
•  elseif                 •    or
•  for                    •    and
•  foreach                •    xor
•  if                     •    catch
•  while
Cyclomatic complexity - example
class Foo {
    public function example() {
        if ($a == $b) {
            if ($a1 == $b1) {
                 fiddle();
            } elseif ($a2 == $b2) {
                 fiddle();
            } else {
                 fiddle();
            }
        } elseif ($e == $f) {
            for ($n = 0; $n < $h; $n++) {
                 fiddle();
            }
        } else {
            fiddle();
        }
    }
}
Cyclomatic complexity - example
class Foo {
    public function example() {             1
        if ($a == $b) {
            if ($a1 == $b1) {
                 fiddle();
            } elseif ($a2 == $b2) {
                 fiddle();
            } else {
                 fiddle();
            }
        } elseif ($e == $f) {
            for ($n = 0; $n < $h; $n++) {
                 fiddle();
            }
        } else {
            fiddle();
        }
    }
}
Cyclomatic complexity - example
class Foo {
    public function example() {             1
        if ($a == $b) {                     2
            if ($a1 == $b1) {
                 fiddle();
            } elseif ($a2 == $b2) {
                 fiddle();
            } else {
                 fiddle();
            }
        } elseif ($e == $f) {
            for ($n = 0; $n < $h; $n++) {
                 fiddle();
            }
        } else {
            fiddle();
        }
    }
}
Cyclomatic complexity - example
class Foo {
    public function example() {             1
        if ($a == $b) {                     2
            if ($a1 == $b1) {               3
                 fiddle();
            } elseif ($a2 == $b2) {
                 fiddle();
            } else {
                 fiddle();
            }
        } elseif ($e == $f) {
            for ($n = 0; $n < $h; $n++) {
                 fiddle();
            }
        } else {
            fiddle();
        }
    }
}
Cyclomatic complexity - example
class Foo {
    public function example() {             1
        if ($a == $b) {                     2
            if ($a1 == $b1) {               3
                 fiddle();
            } elseif ($a2 == $b2) {         4
                 fiddle();
            } else {
                 fiddle();
            }
        } elseif ($e == $f) {
            for ($n = 0; $n < $h; $n++) {
                 fiddle();
            }
        } else {
            fiddle();
        }
    }
}
Cyclomatic complexity - example
class Foo {
    public function example() {             1
        if ($a == $b) {                     2
            if ($a1 == $b1) {               3
                 fiddle();
            } elseif ($a2 == $b2) {         4
                 fiddle();
            } else {
                 fiddle();
            }
        } elseif ($e == $f) {               5
            for ($n = 0; $n < $h; $n++) {
                 fiddle();
            }
        } else {
            fiddle();
        }
    }
}
Cyclomatic complexity - example
class Foo {
    public function example() {             1
        if ($a == $b) {                     2
            if ($a1 == $b1) {               3
                 fiddle();
            } elseif ($a2 == $b2) {         4
                 fiddle();
            } else {
                 fiddle();
            }
        } elseif ($e == $f) {               5
            for ($n = 0; $n < $h; $n++) {   6
                 fiddle();
            }
        } else {
            fiddle();
        }
    }
}
Cyclomatic complexity - example
class Foo {
    public function example() {
        if ($a == $b) {
            if ($a1 == $b1) {
                 fiddle();
            } elseif ($a2 == $b2) {
                 fiddle();
            } else {
                 fiddle();
            }                               6
        } elseif ($e == $f) {
            for ($n = 0; $n < $h; $n++) {
                 fiddle();
            }
        } else {
            fiddle();
        }
    }
}
phploc
phploc 1.6.1 by Sebastian Bergmann.	
	
Directories:                                      6	
Files:                                           20	
	
Lines of Code (LOC):                           5478	
  Cyclomatic Complexity / Lines of Code:       0.13	
Comment Lines of Code (CLOC):                  2143	
Non-Comment Lines of Code (NCLOC):             3335	
	
Namespaces:                                       0	
Interfaces:                                       1	
Classes:                                         18	
  Abstract:                                       2 (11.11%)	
  Concrete:                                      16 (88.89%)	
  Average Class Length (NCLOC):                 191	
Methods:                                        151	
  Scope:	
    Non-Static:                                 143 (94.70%)	
    Static:                                       8 (5.30%)	
  Visibility:	
    Public:                                     116 (76.82%)	
    Non-Public:                                  35 (23.18%)	
  Average Method Length (NCLOC):                 22	
  Cyclomatic Complexity / Number of Methods:   3.72	
	
Anonymous Functions:                              0	
Functions:                                        2	
	
Constants:                                        4	
  Global constants:                               3	
  Class constants:                                1
Cyclomatic complexity - thresholds




                Low     Avg      High    V.High
Complexity      1-4     5-7      8-10    > 11
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)
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)
WMC and AMW

Weighted Method Count – total complexity of a class




Average Method Weight – average complexity of a method
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)
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)
Coverage report
C.R.A.P
C.R.A.P



Change
Risk
Analysis and
  Change Risk Analysis and Predictions




Predictions
C.R.A.P formula




Code coverage = 100%




 Code coverage = 0%
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
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
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;
    }
}
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;
    }
}
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;
    }
}
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;
    }
}
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;
    }
}
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;
    }
}
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;
    }
}
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;
    }
}
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;
    }
}
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;
    }
}
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;
    }
}
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;
    }
}
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;
    }
}
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;
    }
}
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;
    }
}
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;
    }
}
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;
    }
}
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
    }
}
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;
    }
}
PHP Depend
PHP_Depend 0.10.6 by Manuel Pichler	
	
Parsing source files:	
....................                                      20	
	
Executing CyclomaticComplexity-Analyzer:	
.............                                            261	
	
Executing ClassLevel-Analyzer:	
............                                             247	
	
Executing CodeRank-Analyzer:	
.                                                         28	
	
Executing Coupling-Analyzer:	
.............                                            267	
	
Executing Hierarchy-Analyzer:	
............                                             246	
	
Executing Inheritance-Analyzer:	
.                                                         30	
	
Executing NPathComplexity-Analyzer:	
..............                                           283	
	
Executing NodeCount-Analyzer:	
........                                                 174	
	
Executing NodeLoc-Analyzer:	
..........                                               205	
	
Generating pdepend log files, this may take a moment.	
	
Time: 00:05; Memory: 25.50Mb
PHP Mess Detector
Overview pyramid
Size and complexity – direct metrics
Size and complexity – computed proportions
System coupling – direct metrics
System coupling – computed proportions
System inheritance
Complete Overview Pyramid
PHP

Metric         Low          Avg       High
CYCLO/LOC      0.16         0.20      0.24
LOC/NOM        7            10        13
NOM/NOC        4            7         10
NOC/NOP        6            17        26
CALLS/NOM      2.01         2.62      3.2
FANOUT/CALLS   0.56         0.62      0.68
ANDC           0.25         0.41      0.57
AHH            0.09         0.21      0.32

                                   http://pdepend.org/
Metrics visualisation with Sonar
Metrics visualisation with Sonar
Violations reporting
SIG Maintainability Model




--   Very bad
-    Bad
0    Average
+    Good
++   Very good
Technical Debt
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
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)
Questions




Questions?

https://joind.in/4758

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 Poleliving 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 willbe talking about •  Code metrics •  Design metrics What I will not be talking about •  Project metrics https://joind.in/4758
  • 4.
    Most effective codequality measure
  • 6.
    What is ametric? “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 “Gooddesign 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.
  • 11.
    Cyclomatic Complexity Number(CCN) Conditional statements: •  ? •  case •  elseif •  for •  foreach •  if •  while
  • 12.
    CCN2 Conditional statements: •  ? •  && •  case •  || •  elseif •  or •  for •  and •  foreach •  xor •  if •  while
  • 13.
    Cyclomatic complexity Conditional statements: • ? •  && •  case •  || •  elseif •  or •  for •  and •  foreach •  xor •  if •  catch •  while
  • 14.
    Cyclomatic complexity -example class Foo { public function example() { if ($a == $b) { if ($a1 == $b1) { fiddle(); } elseif ($a2 == $b2) { fiddle(); } else { fiddle(); } } elseif ($e == $f) { for ($n = 0; $n < $h; $n++) { fiddle(); } } else { fiddle(); } } }
  • 15.
    Cyclomatic complexity -example class Foo { public function example() { 1 if ($a == $b) { if ($a1 == $b1) { fiddle(); } elseif ($a2 == $b2) { fiddle(); } else { fiddle(); } } elseif ($e == $f) { for ($n = 0; $n < $h; $n++) { fiddle(); } } else { fiddle(); } } }
  • 16.
    Cyclomatic complexity -example class Foo { public function example() { 1 if ($a == $b) { 2 if ($a1 == $b1) { fiddle(); } elseif ($a2 == $b2) { fiddle(); } else { fiddle(); } } elseif ($e == $f) { for ($n = 0; $n < $h; $n++) { fiddle(); } } else { fiddle(); } } }
  • 17.
    Cyclomatic complexity -example class Foo { public function example() { 1 if ($a == $b) { 2 if ($a1 == $b1) { 3 fiddle(); } elseif ($a2 == $b2) { fiddle(); } else { fiddle(); } } elseif ($e == $f) { for ($n = 0; $n < $h; $n++) { fiddle(); } } else { fiddle(); } } }
  • 18.
    Cyclomatic complexity -example class Foo { public function example() { 1 if ($a == $b) { 2 if ($a1 == $b1) { 3 fiddle(); } elseif ($a2 == $b2) { 4 fiddle(); } else { fiddle(); } } elseif ($e == $f) { for ($n = 0; $n < $h; $n++) { fiddle(); } } else { fiddle(); } } }
  • 19.
    Cyclomatic complexity -example class Foo { public function example() { 1 if ($a == $b) { 2 if ($a1 == $b1) { 3 fiddle(); } elseif ($a2 == $b2) { 4 fiddle(); } else { fiddle(); } } elseif ($e == $f) { 5 for ($n = 0; $n < $h; $n++) { fiddle(); } } else { fiddle(); } } }
  • 20.
    Cyclomatic complexity -example class Foo { public function example() { 1 if ($a == $b) { 2 if ($a1 == $b1) { 3 fiddle(); } elseif ($a2 == $b2) { 4 fiddle(); } else { fiddle(); } } elseif ($e == $f) { 5 for ($n = 0; $n < $h; $n++) { 6 fiddle(); } } else { fiddle(); } } }
  • 21.
    Cyclomatic complexity -example class Foo { public function example() { if ($a == $b) { if ($a1 == $b1) { fiddle(); } elseif ($a2 == $b2) { fiddle(); } else { fiddle(); } 6 } elseif ($e == $f) { for ($n = 0; $n < $h; $n++) { fiddle(); } } else { fiddle(); } } }
  • 22.
    phploc phploc 1.6.1 bySebastian Bergmann. Directories: 6 Files: 20 Lines of Code (LOC): 5478 Cyclomatic Complexity / Lines of Code: 0.13 Comment Lines of Code (CLOC): 2143 Non-Comment Lines of Code (NCLOC): 3335 Namespaces: 0 Interfaces: 1 Classes: 18 Abstract: 2 (11.11%) Concrete: 16 (88.89%) Average Class Length (NCLOC): 191 Methods: 151 Scope: Non-Static: 143 (94.70%) Static: 8 (5.30%) Visibility: Public: 116 (76.82%) Non-Public: 35 (23.18%) Average Method Length (NCLOC): 22 Cyclomatic Complexity / Number of Methods: 3.72 Anonymous Functions: 0 Functions: 2 Constants: 4 Global constants: 3 Class constants: 1
  • 23.
    Cyclomatic complexity -thresholds Low Avg High V.High Complexity 1-4 5-7 8-10 > 11
  • 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 WeightedMethod 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)
  • 29.
  • 31.
  • 32.
    C.R.A.P Change Risk Analysis and Change Risk Analysis and Predictions Predictions
  • 33.
    C.R.A.P formula Code coverage= 100% Code coverage = 0%
  • 35.
    NPATH – acyclicexecution 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 – acyclicexecution 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 classFoo { 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 classFoo { 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 classFoo { 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 classFoo { 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 classFoo { 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 classFoo { 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 classFoo { 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 classFoo { 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 classFoo { 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 classFoo { 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 classFoo { 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 classFoo { 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 classFoo { 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 classFoo { 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 classFoo { 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 classFoo { 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 classFoo { 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 classFoo { 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 classFoo { 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; } }
  • 56.
    PHP Depend PHP_Depend 0.10.6by Manuel Pichler Parsing source files: .................... 20 Executing CyclomaticComplexity-Analyzer: ............. 261 Executing ClassLevel-Analyzer: ............ 247 Executing CodeRank-Analyzer: . 28 Executing Coupling-Analyzer: ............. 267 Executing Hierarchy-Analyzer: ............ 246 Executing Inheritance-Analyzer: . 30 Executing NPathComplexity-Analyzer: .............. 283 Executing NodeCount-Analyzer: ........ 174 Executing NodeLoc-Analyzer: .......... 205 Generating pdepend log files, this may take a moment. Time: 00:05; Memory: 25.50Mb
  • 57.
  • 58.
  • 59.
    Size and complexity– direct metrics
  • 60.
    Size and complexity– computed proportions
  • 61.
    System coupling –direct metrics
  • 62.
    System coupling –computed proportions
  • 63.
  • 64.
  • 65.
    PHP Metric Low Avg High CYCLO/LOC 0.16 0.20 0.24 LOC/NOM 7 10 13 NOM/NOC 4 7 10 NOC/NOP 6 17 26 CALLS/NOM 2.01 2.62 3.2 FANOUT/CALLS 0.56 0.62 0.68 ANDC 0.25 0.41 0.57 AHH 0.09 0.21 0.32 http://pdepend.org/
  • 66.
  • 67.
  • 68.
  • 69.
    SIG Maintainability Model -- Very bad - Bad 0 Average + Good ++ Very good
  • 70.
  • 71.
    Summary “We believe thatsoftware 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)
  • 73.