SlideShare a Scribd company logo
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
PHP Benelux 2012: Magic behind the numbers. Software metrics in practice
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
PHP Benelux 2012: Magic behind the numbers. Software metrics in practice
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%
PHP Benelux 2012: Magic behind the numbers. Software metrics in practice
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

More Related Content

PDF
Static Optimization of PHP bytecode (PHPSC 2017)
PDF
Creating Domain Specific Languages in Python
PDF
Fantastic DSL in Python
PDF
Pim Elshoff "Technically DDD"
PPSX
C# 6.0 - April 2014 preview
PDF
Что нам готовит грядущий C#7?
PDF
Nikita Popov "What’s new in PHP 8.0?"
PDF
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
Static Optimization of PHP bytecode (PHPSC 2017)
Creating Domain Specific Languages in Python
Fantastic DSL in Python
Pim Elshoff "Technically DDD"
C# 6.0 - April 2014 preview
Что нам готовит грядущий C#7?
Nikita Popov "What’s new in PHP 8.0?"
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017

What's hot (20)

PDF
Just-In-Time Compiler in PHP 8
PDF
.NET 2015: Будущее рядом
PPTX
Programming Java - Lection 04 - Generics and Lambdas - Lavrentyev Fedor
PDF
Php in the graph (Gremlin 3)
PPSX
What's New In C# 7
PPTX
Lecture 7, c++(complete reference,herbet sheidt)chapter-17.
PDF
Lucio Floretta - TensorFlow and Deep Learning without a PhD - Codemotion Mila...
PDF
Python Puzzlers
PPTX
TDC2016SP - Trilha .NET
PDF
PPT
PHP and MySQL
PDF
Voce Tem Orgulho Do Seu Codigo
PPSX
Tuga IT 2017 - What's new in C# 7
DOC
12. stl örnekler
PDF
Is Haskell an acceptable Perl?
PPT
SQL Devlopment for 10 ppt
PPSX
Tuga it 2016 - What's New In C# 6
PPTX
TDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDB
PPTX
More on Classes and Objects
DOC
Fee managment system
Just-In-Time Compiler in PHP 8
.NET 2015: Будущее рядом
Programming Java - Lection 04 - Generics and Lambdas - Lavrentyev Fedor
Php in the graph (Gremlin 3)
What's New In C# 7
Lecture 7, c++(complete reference,herbet sheidt)chapter-17.
Lucio Floretta - TensorFlow and Deep Learning without a PhD - Codemotion Mila...
Python Puzzlers
TDC2016SP - Trilha .NET
PHP and MySQL
Voce Tem Orgulho Do Seu Codigo
Tuga IT 2017 - What's new in C# 7
12. stl örnekler
Is Haskell an acceptable Perl?
SQL Devlopment for 10 ppt
Tuga it 2016 - What's New In C# 6
TDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDB
More on Classes and Objects
Fee managment system
Ad

Viewers also liked (7)

PDF
SimpleVOC OPEN – Yet another Memcached? (Froscon 2010 talk, german)
PDF
One Click Deployment with Jenkins
PDF
Scrum, Kanban oder vielleicht beides?
PDF
The Original Hypertext Preprocessor
KEY
Localisation typo3
PDF
Verlernte Agilität - Schleichende Fehler in agilen Prozessen
PDF
Open a window, see the clouds - php|tek 2011
SimpleVOC OPEN – Yet another Memcached? (Froscon 2010 talk, german)
One Click Deployment with Jenkins
Scrum, Kanban oder vielleicht beides?
The Original Hypertext Preprocessor
Localisation typo3
Verlernte Agilität - Schleichende Fehler in agilen Prozessen
Open a window, see the clouds - php|tek 2011
Ad

Similar to PHP Benelux 2012: Magic behind the numbers. Software metrics in practice (20)

PDF
PHP Forum Paris 2012: Magic behind the numbers. Software metrics in practice
PDF
Development By The Numbers - ConFoo Edition
PDF
Development by the numbers
ODP
Red Flags in Programming
PPTX
Magic behind the numbers - software metrics in practice
PDF
Dutch PHP Conference 2013: Distilled
PDF
02 - Second meetup
PDF
PHP 5.3 and Lithium: the most rad php framework
PDF
Phpquick
PDF
Php Inspections (EA Extended): if-conditions optimization
PDF
Best practices for crafting high quality PHP apps - PHP UK 2019
PDF
Zend Certification Preparation Tutorial
PDF
Living With Legacy Code
PPT
Discovering joy
PDF
Pf congres20110917 data-structures
PDF
Measuring maintainability; software metrics explained
PDF
Best practices for crafting high quality PHP apps (Bulgaria 2019)
PDF
Machine vision and device integration with the Ruby programming language (2008)
PDF
Functional programming in ruby
PDF
Being functional in PHP (DPC 2016)
PHP Forum Paris 2012: Magic behind the numbers. Software metrics in practice
Development By The Numbers - ConFoo Edition
Development by the numbers
Red Flags in Programming
Magic behind the numbers - software metrics in practice
Dutch PHP Conference 2013: Distilled
02 - Second meetup
PHP 5.3 and Lithium: the most rad php framework
Phpquick
Php Inspections (EA Extended): if-conditions optimization
Best practices for crafting high quality PHP apps - PHP UK 2019
Zend Certification Preparation Tutorial
Living With Legacy Code
Discovering joy
Pf congres20110917 data-structures
Measuring maintainability; software metrics explained
Best practices for crafting high quality PHP apps (Bulgaria 2019)
Machine vision and device integration with the Ruby programming language (2008)
Functional programming in ruby
Being functional in PHP (DPC 2016)

More from Sebastian Marek (14)

PDF
The Journey Towards Continuous Integration
PDF
CodeClub - Teaching the young generation programming
PDF
Praktyczne code reviews - PHPConPl
PDF
Managing and Monitoring Application Performance
PDF
Ten Commandments Of A Software Engineer
PDF
Continuous Inspection: Fight back the 7 deadly sins of a developer!
PDF
Test your code like a pro - PHPUnit in practice
PDF
Effective code reviews
PDF
Effective code reviews
PPTX
Ten Commandments Of A Software Engineer
PDF
Back to basics - PHPUnit
ODP
Back to basics - PHP_Codesniffer
ODP
Sonar - the ring to rule them all
ODP
vfsStream - effective filesystem mocking
The Journey Towards Continuous Integration
CodeClub - Teaching the young generation programming
Praktyczne code reviews - PHPConPl
Managing and Monitoring Application Performance
Ten Commandments Of A Software Engineer
Continuous Inspection: Fight back the 7 deadly sins of a developer!
Test your code like a pro - PHPUnit in practice
Effective code reviews
Effective code reviews
Ten Commandments Of A Software Engineer
Back to basics - PHPUnit
Back to basics - PHP_Codesniffer
Sonar - the ring to rule them all
vfsStream - effective filesystem mocking

Recently uploaded (20)

PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
DOCX
The AUB Centre for AI in Media Proposal.docx
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
MIND Revenue Release Quarter 2 2025 Press Release
PDF
Network Security Unit 5.pdf for BCA BBA.
PPTX
Programs and apps: productivity, graphics, security and other tools
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
Electronic commerce courselecture one. Pdf
PPTX
Cloud computing and distributed systems.
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PPTX
MYSQL Presentation for SQL database connectivity
Agricultural_Statistics_at_a_Glance_2022_0.pdf
The AUB Centre for AI in Media Proposal.docx
“AI and Expert System Decision Support & Business Intelligence Systems”
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
MIND Revenue Release Quarter 2 2025 Press Release
Network Security Unit 5.pdf for BCA BBA.
Programs and apps: productivity, graphics, security and other tools
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
Advanced methodologies resolving dimensionality complications for autism neur...
Mobile App Security Testing_ A Comprehensive Guide.pdf
Electronic commerce courselecture one. Pdf
Cloud computing and distributed systems.
Diabetes mellitus diagnosis method based random forest with bat algorithm
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Dropbox Q2 2025 Financial Results & Investor Presentation
Chapter 3 Spatial Domain Image Processing.pdf
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Building Integrated photovoltaic BIPV_UPV.pdf
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
MYSQL Presentation for SQL database connectivity

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
  • 4. Most effective code quality measure
  • 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.
  • 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 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
  • 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 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)
  • 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 – 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; } }
  • 56. 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
  • 59. Size and complexity – direct metrics
  • 60. Size and complexity – computed proportions
  • 61. System coupling – direct metrics
  • 62. System coupling – computed proportions
  • 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/
  • 69. SIG Maintainability Model -- Very bad - Bad 0 Average + Good ++ Very good
  • 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)