SlideShare ist ein Scribd-Unternehmen logo
1 von 54
Downloaden Sie, um offline zu lesen
Die Macht der Zahlen



                 Source Code Metriken



Prof. Dr. Wolfgang Golubski     Gerrit Beine, M.Sc.
      golubski@fh-zwickau.de      mail@gerritbeine.com


                                                         1
Einige ausgewählte Metriken




                              2
McCabes zyklomatische Komplexität




                                    3
McCabes zyklomatische Komplexität


●   Literatur: A Complexity Measure; Thomas J. McCabe
     ●   IEEE Transactions on Software Engineering, Vol. SE-2, No.4, December 1976
     ●   http://www.literateprogramming.com/mccabe.pdf
●   Die zyklomatische Komplexität basiert auf der Graphentheorie
●   Ursprünglich für FORTRAN erdacht
●   Auf alle strukturierten und prozeduralen Sprachen anwendbar
●   Entscheidungen im Programm werden zu Knoten im Graph
●   Programmlogik wird als Kanten des Graphs interpretiert
                                   v (G)=e−n+2∗p
●   Zyklomatische Komplexität:
     ●   e = edges, Kanten im Graph
     ●   n = nodes, Knoten im Graph
     ●   p = parts, (unabhängige) Teile des Graph




                                                                                     4
Algorithmische Ermittlung der zyklomatischen Komplexität


●   Theorem: v(G) ist gleich der Anzahl der                               A
    unabhängigen Zyklen des Graph.
●   Ermittlung durch Zweigüberdeckung:
                                                                      B   C   D
     ●   Übertragung des Graphen in einen
         Baum
     ●   Jeder Pfad im Graph entspricht                               E
         einem Pfad im Baum
     ●   Anwendung der Tiefensuche                            A           F
     ●   Es werden nur Knoten untersucht,
         die noch nicht besucht wurden                B       C       D
     ●   Wurde ein Knoten besucht, ist ein
         neuer unabhängiger Kreis entdeckt            E       F       C
●   Vorgehen liefert gleichzeitig Testfälle für
    den Graph
                                                  B       A       F


                                                                  A

                                                                                  5
Anwendung der zyklomatischen Komplexität auf objektorienten Code


●   Methodenbasiert
     ●   Es werden die Kontrollstrukturen innerhalb von Methoden untersucht
     ●   Mögliche Ergebnisse:
          ●   v(G) für konkrete Methode, avg v(G) pro Methode / Klasse / Package (sinnfrei)
●   Prozessbasiert
     ●   Sämtliche für einen Prozess relevanten Methoden werden als unabhängige
         Teilgraphen (Components) betrachtet
     ●   e sind die Kanten der Kontrollstrukturgraphen aller Methoden
     ●   n sind die Knoten der Kontrollstrukturgraphen aller Methoden
     ●   p ist die Anzahl der beteiligten Methoden
     ●   Berechnung ist aufwändig (abhängig von Kopplung)
     ●   Algorithmus liefert aber sehr interessante Aussagen
         u.a. über die Gesamtkomplexität von Prozessen




                                                                                              6
Die Halstead-Metriken




                        7
Die Halstead-Metriken


●   Literatur: Elements of Software Science; Maurice H. Halstead
     ●   Elsevier Science Inc., New York, 1977
●   Halsteadt definierte eine Reihe von Metriken zur Komplexitäts- und Aufwandsschätzung
     ●   Program vocabulary (n)
     ●   Program length (N)
     ●   Calculated program length
     ●   Program volume (V)
     ●   Program difficulty level (D)
     ●   Program level (L)
     ●   Effort to implement (E)
     ●   Time to implement (T)
     ●   Number of delivered bugs (B)




                                                                                           8
Berechnung der Halstead-Metriken


●   Unique Operators and Operands: n1, n2
●   Total amount of Operators and Operands: N1, N2
●   Program vocabulary:                     n=n1+n2
●   Program length:                         N =N1+N2
●   Calculated program length:              ̂
                                            N =n1∗log 2 (n1)+n2∗log 2 (n2)
●   Program volume:                         V =N∗log2 (n)
                                                N1    n2
●   Program difficulty level:               D=( )∗( )
                                                 2     2
    Program level:                             1
●
                                            L=
                                               D
●   Effort to implement:                    E=V ∗D
                                               E
●   Time to implement:                      T=
                                               18 2
●   Number of delivered bugs:                   E3                 V
                                            B=      oder neu : B=
                                               3000               3000




                                                                             9
Kritik an Halsteadts Metriken


●   Definition von Operator und Operand ist nicht festgelegt
●   Fenton, N., Software Measurement: A Necessary Scientific Basis. In IEEE Transactions on
    Software Engineering, 1004, vol. 20(3), pp. 199-206.
     ●   Halsteads Metriken liefern keine Aussagen zur Komplexität, werden aber oft dafür
         herangezogen
●   Al-Qutaish, R.E., and Abran, A., An analysis of the design and definitions of Halstead’s
    metrics, In 15th Int. Workshop on Software Measurement, 2005, pp. 337-352.
     ●   Die Unklarheit von Halsteads Definitionen führt zu verschiedenen Interpretationen
     ●   Die Anwendbarkeit auf moderne Programmiersprachen ist nicht festgelegt
●   Beser, N., Foundations and experiments in software science. In Selected Papers of the
    1982 ACM SIGMETRICS Workshop on Software Metrics: Part 2, 1982, pp. 48-72. und
    Davies, G., and Tan, A., A note on metrics of Pascal programs. In ACM SIGPLAN Notices,
    1987, vol. 22(8), pp. 39-44.
     ●   Die Formel für N überschätzt die Länge kleiner Programme und unterschätzt die
         Länge großer Programme




                                                                                               10
Der Maintainability Index




                            11
Der Maintainability Index


●   Literatur: Oman, P., Hagemeister, J.: Metrics for assessing Software System Maintainability
     ●   IEEE Int. Conference on Software Maintenance, 1994, S. 337
●   Zusammenhang zwischen Codeeigenschaften und Wartungsaufwand
●   Basiert auf anderen Metriken
     ●   Aufwand nach Halstead (E)
     ●   Zyklomatische Komplexität nach McCabe (G)
     ●   Modulgröße (LOC)
●   In einer Überarbeitung kam noch hinzu
     ●   Kommentierungsgrad (CMT) prozentualer Anteil an den LOC
     ●   Halstead-Volumen (V) alternativ zum Aufwand nach Halstead (E)




                                                                                             12
Der Maintainability Index


●   1992: ursprüngliche Formel
    MI =171−5,2∗ln (E)−0,23∗ln (G)−16,2∗ln (LOC )
●   1994: Berücksichtigung von Kommentaren
    MI =171−5,2∗ln (V )−0,23∗ln (G)−16,2∗ln (LOC )+50∗sin √ 2,4∗CMT
●   Interpretation
     ●   MI > 85: gute Wartbarkeit
     ●   65<MI<85: mittlere Wartbarkeit
     ●   MI<65: schlechte Wartbarkeit
●   Normalisierter MI von Microsoft
    MI =MAX (0,(171−5,2∗ln (V )−0,23∗ln (G)−16,2∗ln (LOC ))∗100/171)
●   Interpretation
     ●   0-9 = Rot
     ●   10-19 = Gelb
     ●   20-100 = Grün



                                                                       13
Kritik am Maintainability Index


●   Korrektheit von MI wurde nur über Korrelation mit subjektivem Empfinden von
    Wartbarkeits-Experten geprüft (0,81-0,93)
●   Reduzieren von Software auf einen einzigen Wert ist nur als Trend aussagekräftig
●   Beschränkung auf spezifische Metriken reduziert die Anwendbarkeit auf moderne
    Programmiersprachen
●   Sneed, H.: “Software muss messbar werden”, Zeitschrift für Information Management, Nr.
    4, 1991, S. 39
     ●   Nur 40% der Wartungskosten werden von MI tangiert, der Rest teilt sich zwischen
         Wartungspersonal und Wartungsumgebung auf




                                                                                           14
Die Robert C. Martin-Metriken




                                15
Die Robert C. Martin-Metriken


●   Literatur: OO Design Quality Metrics; An Analysis of Dependencies; By Robert Martin
     ●   http://www.objectmentor.com/resources/articles/oodmetrc.pdf
●   Die Martin-Metriken zielen auf folgende Clean Code Prinzipien ab
     ●   Single Responsibility Principle (SRP)
     ●   Separation of Concerns (SOC)
     ●   Interface Segregation Principle (ISP)
     ●   Dependecy Inversion Principle (DIP)
     ●   Information Hiding Principle (IHP)
     ●   Open Closed Principle (OCP)




                                                                                          16
Instabilität


●   Ca: Afferent Couplings: Anzahl der Klassen außerhalb der Kategorie, die von Klassen
    innerhalb der Kategorie abhängen – eingehende Abhängigkeiten
●   Ce: Efferent Couplings: Anzahl der Klassen außerhalb der Kategorie, von denen Klassen
    innerhalb der Kategorie abhängen – ausgehende Abhängigkeiten
●   Eselsbrücke: Inversion Ca = eingehend, Ce = ausgehend

                         Ce
●   Instability: I =         , I ∈[0,1]; ∑ Ce= ∑ Ca
                       Ca+Ce            Kategorien Kategorien


●   Keine ausgehenden Abhängigkeiten:
    Hohe Stabilität, Tendenz ist I = 0
●   Keine eingehenden Abhängigkeiten:
    Hohe Instabilität, Tendenz ist I = 1
●   Grenzwertbetrachtungen:
             Ce                  Ce                           Ce                    Ce
    lim          =0      lim         =1               lim         =1      lim           =0
    Ce → 0 Ca+Ce        Ce → ∞ Ca+Ce                 Ca → 0 Ca+Ce         Ca →∞   Ca+Ce




                                                                                             17
Instabilität


●   Hohe Stabilität (I nahe 0) ist erforderlich für
     ●   System-Kerne
             Komponenten, um die eine Software herum gebaut wird.
     ●   Datenmodelle
             Ein gutes Beispiel sind EJB3 Entities. Diese sollten von keinen anderen
             Komponenten einer Software abhängen.
●   Hohe Instabilität (I nahe 1) entsteht bei
     ●   Implementierung von externen Schnittstellen
             Als Beispiel kann die Implementierung eines WebService dienen, der
             Funktionalität nach außen zur Verfügung stellt.
             Von solchen Komponenten darf innerhalb des Systems nichts abhängen.
     ●   komplexen User Interfaces
             User Interfaces führen oftmals viele Komponenten zusammen.
             Somit entstehen hohe Werte für ausgehende Abhängigkeiten.




                                                                                       18
Instabilität


        ●   Keine Pakete mit I=0 →
               ●   Kein Systemkern
               ●   Zyklische Abhängigkeiten vorhanden
        ●   Viele Pakete mit I=1 →
               ●   Hohe Wartungsaufwände bei kleinen
                   Änderungen
        ●   Prinzip:
            Je mehr Pakete mit höherer Instabilität,
            desto größer ist der Domino-Effekt bei
            Änderungen.
        ●   Ziel:
            Möglichst viele stabile Pakete.
            Software neigt leider dazu, sich
            entgegengesetzt zu entwicklen.




                                                       19
Abstraktion


●   NoAC: Number of Abstract Classes: Alle abstrakten Klassen eines Paketes
●   NoCC: Number of Concrete Classes: Alle nicht abstrakten Klassen eines Paketes
●   NoI: Number of Interfaces: Alle Schnittstellen eines Paketes
●   NoC: Number of Classes = NoAC+NoCC: Alle Klassen eines Paketes


    Abstractness A=          NoAC+ NoI   NoACI
●
                                       =       =, A ∈[0, 1]
                          NoCC+NoAC+NoI NoCI

●   Keine abstrakten Klassen und Schnittstellen:
    Niedrige Abstraktion, Tendenz ist A = 0
●   Ausschließlich abstrakte Klassen und Schnittstellen:
    Hohe Abstraktion, Tendenz ist A = 1
●   Grenzwertbetrachtungen:

                       NoAC+NoI                                       NoAC+NoI
        lim                       =0                   lim                       =1
    NoAC+ NoI → 0   NoCC+NoAC+NoI                  NoAC+ NoI → ∞   NoCC+NoAC+NoI
                 NoAC+NoI                                       NoAC+NoI
     lim                     =1                      lim                   =0
    NoCC →0   NoCC+ NoAC+NoI                       NoCC →∞   NoCC+NoAC+NoI

                                                                                      20
Abstraktion


       ●   Keine Pakete mit A=1 →
              ●   Schnittstellen nicht einzeln
                  distributierbar
       ●   Viele Pakete mit A=0 →
              ●   Erweiterungen (OCP) nicht möglich
       ●   Prinzip:
           Abstrakte Pakete sind entsprechend des
           OCP leichter zu erweitern als nicht
           abstrakte Pakete.
       ●   Ziel:
           Definierte abstrakte Pakete, um
           Schnittstellen zu separieren. Gute
           Abstraktion benötigt viel Zeit.




                                                      21
Distanz


●   Pakete sollten ausschließlich von stabileren Paketen (idealerweise auch abstrakteren
    Paketen) abhängen. (ISP)
     ●   Das ist die Grundlage für Inversion of Control bzw. Dependency Injection
●   Zusammenhänge zwischen Abstraktion und Instabilität
     ●   Abstrakte Pakete (A=1) sollten stabil sein (I=0), d.h. keine ausgehenden
         Abhängigkeiten besitzen. Damit sind sie offen für Erweiterungen und geschlossen
         gegenüber Modifikationen. (OCP)
     ●   Instabile Pakete (I=1) sollten nicht abstrakt (A=0) sein. Sie sind nicht mehr
         erweiterbar, unterliegen aber eine hohe Änderungswahrscheinlichkeit.
     ●   Pakete mit balancierter Abstraktion (A=0,5) und Instabilität (I=0,5) sind noch
         teilweise erweiterbar, unterliegen allerdings schon einer gewissen
         Änderungswahrscheinlichkeit.
     ●   Abstraktion und Instabilität sollten ausbalanciert sein.




                                                                                           22
Distanz


                                                                           ●    Balance zwischen A und I ergibt einen
                                                                                Graphen, der folgender Formel genügt:
                                                                           ●    Distance: Dn=∣A+I−1∣, Dn∈[0,1]
                                                                           ●    Pakete, die sich nahe der Main Sequence
                                                                                befinden, sind ausbalanciert.
                                                                           ●    Je weiter ein Paket von der Main
                                                                                Sequence entfernt ist, desto schwieriger
                                                                                wird seine Verwendung (Area of
                                                                                Uselessness bei A=1 und I=1) oder seine
                                                                                Wartung (Area of Pain bei A=0 und I=0)
                                                                           ●    Ziel:
                                                                                Optimale Pakete befinden sich an einem
                                                                                der Endpunkte der Main Sequence, die
                                                                                Entfernung zur Main Sequence (=Distanz)
Quelle: http://www.objectmentor.com/resources/articles/oodmetrc.pdf
                                                                                sollte minimal sein.




                                                                                                                        23
Einige ausgewählte Metriken




Chidamber & Kemerers OO-Metriken




                                      24
Chidamber & Kemerers OO-Metriken


●   Literatur: S. R. Chidamber, C.F. Kemerer, A Metrics Suite for Object Oriented Design
     ●   IEEE Transactions on Software Engineering, 20(6), 1994, S. 476-493
●   Sammlung von Metriken zur Bewertung objektorientierter Systeme
     ●   Weighted Method Count (WMC)
     ●   Coupling Between Object Classes (CBO)
     ●   Depth of Inheritance Tree (DIT)
     ●   Number of Children (NOC)
     ●   Response For a Class (RFC)
     ●   Lack of Cohesion in Methods (LCOM)




                                                                                           25
Weighted Method Count (WMC) / Coupling Between Object Classes (CBO)


                    WMC                                          CBO
                      n
●   Formel:   WMC=∑ c i                      ●   Anzahl der Klassen, die von einer Klasse
                     i=1
●   Als Komplexitätsfunktion kann z.B. die       benutzt werden
    zyklomatische Komplexität dienen         ●   Ein hoher Wert für CBO deutet auf
●   Kann als Wartungsmaß dienen, da eine         Änderungsaufwände hin
    größere Anzahl komplexer Methoden        ●   Entspricht dem Ce der Martin-Metrik auf
    höhere Wartungsaufwände verursachen          Klassenebene
    kann                                     ●   Je höher der Wert von CBO, desto höher
●   Bei Vererbung führen hohe Werte von          der Wert der Instability
    WMC zu engen Kopplungen                  ●   Fokus auf Struktur
●   Kritik: Attribute von Klassen werden
    nicht berücksichtigt
●   Clean-Code-Prinzip: SRP
    Single Responsibility Principle




                                                                                            26
Number of Children (NOC) / Depth of Inheritance Tree (DIT)


                    NOC                                            DIT

●   Maß für die Anzahl unmittelbar             ●   Tiefe der Verbungshierarchie einer Klasse
    abgeleiteter Klassen                       ●   Anzahl geerbter Eigenschaften steigt mit
●   Ein hoher Wert für NOC ist ein Indiz für       höherer DIT
    häufige Wiederverwendung                   ●   Klassen mit hoher DIT können nicht
●   Änderungsaufwand für Klassen mit               isoliert betrachtet werden
    hohem Wert für NOC ist hoch                ●   Als Maximalwert für den DIT wird im
●   Testaufwand für Klassen mit hohem NOC          Allgemeinen 7 angesehen
    ist sehr hoch                              ●   Clean-Code-Prinzip: FCoI
●   Clean-Code-Prinzip: FCoI                       Favour Composition over Inheritance
    Favour Composition over Inheritance        ●   Clean-Code-Prinzip: IHP
●   Clean-Code-Prinzip: OCP                        Information Hiding Principle
    Open Closed Principle                      ●   Clean-Code-Prinzip: OCP
                                                   Open Closed Principle




                                                                                          27
Response For a Class (RFC) / Lack of Cohesion in Methods (LCOM)


                     RFC                                           LCOM

●   Response Set: Alle Methoden einer Klasse   ●   Maß für die gemeinsame Nutzung von
    und die von den Methoden benutzten             Attributen einer Klasse durch ihre
    Methoden anderer Klassen                       Methoden
●   Hoher Wert für RFC deutet auf schlechtes   ●   Ein hoher Wert von LCOM weist auf
    Design hinsichtlich der Separation of          schlechtes Design im Sinne der
    Concerns hin                                   Separation of Concerns hin
●   RFC und CBO korrellieren im Allgemeinen    ●   Klassen mit hohem LCOM sollten geteilt
●   Fokus auf Interaktion                          werden
●   Clean-Code-Prinzip: SRP
                                               ●   Clean-Code-Prinzip: SRP
    Single Responsibility Principle                Single Responsibility Principle
●   Clean-Code-Prinzip:
    Tell, don't ask




                                                                                        28
Fragen und Antworten




                       29
Das Problem mit der Kopplung




                               30
Das Problem mit der Kopplung


               ●   Reale Anwendung
               ●   Anwendung enthält rund 35 Entitäten
               ●   Durchschnittliche Kopplung liegt bei
                   mehr als 30!

               ●   Wartung nahezu unmöglich

               ●   Unglücklicherweise sagt der
                   Maintainability Index: 165




                                                          31
Welche Metriken sind wichtig und weit verbreitet?




                                                    32
Welche Metriken sind wichtig und weit verbreitet?


●   Am weitesten verbreitet sind mit Sicherheit die Metrik der Lines of Code, die
    zyklomatische Komplexität und der Maintainability Index
●   Die Verbreitung sagt aber nichts über den Nutzen einer Metrik in einem konkreten Projekt
    aus
●   Oft werden weit verbreitete Metriken völlig falsch angewendet und damit mehr Schaden
    produziert, als Nutzen geschaffen

●   Wichtig sind immer genau die Metriken, die die Antworten auf die Fragen liefern, die sich
    aus dem Ziel eines Projektes ergeben
●   Es sollte nie nur eine Metrik herangezogen werden, sondern idealerweise Metriken, die
    orthogonal zueinander messen
●   Gut ist auch der Ansatz, immer zwei Metriken zu nutzen, die die gleiche Frage
    beantworten: Ist die Antwort identisch, ist sie mit höherer Wahrscheinlichkeit richtig




                                                                                             33
Welche Tools können verwendet werden?




                                        34
Welche Tools können verwendet werden?


●   Unter Java
     ●   JDepend: Martin
     ●   DependencyFinder & OOMetrics: Martin, Chidamber & Kemerer
     ●   PMD: Zyklomatische Komplexität, NPath
     ●   CheckStyle: Zyklomatische Komplexität, NPath
●   Unter PHP
     ●   PHP Mess Detector: Zyklomatische Komplexität, NPath
     ●   PhpDepend: Martin
●   Unter .NET
     ●   Dependometer: Chidamber & Kemerer




                                                                     35
Wie würde ein ausbalanciertes Klassendesign
     aussehen (z.B. I = 0.5 und A=0.5)?




                                              36
Wie würde ein ausbalanciertes Klassendesign aussehen?


●   Balanciert ist das Design nicht nur bei I=0,5 und A=0,5, sondern entlang der gesamten
    Main Sequence
●   Der Idealzustand ist, dass jedes Paket entweder bei I=1 und A=0 oder I=0 und A=1
    anzusiedeln ist.
●   Praktisch ist das nicht zu realisieren (im Sinne einer wirtschaftlichen Entwicklung),
    allerdings ist es nicht das Ziel, I=0,5 und A=0,5 zu erreichen.
●   Das Abstract-Stable-Principle besagt, dass ein Paket so stabil wie abstrakt sein soll:
                                            A ≃1−I




                                                                                             37
Wie würde ein ausbalanciertes Klassendesign aussehen?


      IF                                          Ca   Ce    I     A
                                Bild 1
M            E
                                Model             2    0     0     0
      IM                        Interfaces        1    1    0,5    1
                                Implementierung   0    3     1     0
                                Exceptions        1    0     0     0
      IF                        Bild 2
                                Model             2    0     0     0
M            E                  Interfaces        1    2    0,66   1
      IM                        Implementierung   0    3     1     0
                                Exceptions        2    0     0     0




                                                                       38
Wie würde ein ausbalanciertes Klassendesign aussehen?


      IF                                          Ca   Ce    I     A
                                Bild 3
M            E
                                Model             3    0     0     0
      IM                        Interfaces        2    1    0,33   1
                                Implementierung   0    3     1     0
                                Exceptions        2    0     0     0
      IF                        Model             2    1    0,33   0
                                Interfaces        1    1    0,5    1
M            E                  Implementierung   0    5     1     0
      IM                        Exceptions        1    0     0     0




                                                                       39
Wann ist es sinnvoll die Komplexität zu verteilen,
bereits während der Programmierung oder erst beim
                    Refactoring?




                                                   40
Wann ist es sinnvoll die Komplexität zu verteilen,
          bereits während der Programmierung oder erst beim Refactoring?

●   Refactoring ist Programmierung
●   Im Sinne des Test Driven Development
     ●   Zunächst Funktionalität realisieren
     ●   Danach Komplexität reduzieren




                                                                           41
Stellt die "Auslagerung" der Komplexität (z.B. einer
Methode) nicht einen Widerspruch hinsichtlich der
                  Wartbarkeit dar?




                                                       42
Stellt die "Auslagerung" der Komplexität (z.B. einer Methode)
              nicht einen Widerspruch hinsichtlich der Wartbarkeit dar?

●   Frage wurde bezüglich der zyklomatischen Komplexität gestellt
●   Widersprucht besteht nicht im Sinne der Separation of Concerns
     ●   Inhaltlich verschiedenes voneinander Trennen schafft Übersichtlichkeit
     ●   In objektorientierten Sprachen Polymorphismus als Ersatz für Kontrollstrukturen
         verwenden führt zum Verschwinden von Knoten aus dem Graph
     ●   Polymorphe Methoden bearbeiten jeweils nur einen konkreten Typ:
         Daraus resultierende Vereinfachung leuchtet ein :-)




                                                                                           43
Wie wirkt sich die Verteilung der Komplexität auf
das Laufzeitverhalten (und den Speicherverbrauch)
              von Programmen aus?




                                                     44
Wie wirkt sich die Verteilung der Komplexität auf das Laufzeitverhalten
                  (und den Speicherverbrauch) von Programmen aus?

●   Im besten Falle positiv, manchmal gar nicht und hin und wieder negativ.
●   Sichtweise 1: Dynamisches Laden von Programmteilen
     ●   Es werden nur die Klassen überhaupt geladen, die auszuführenden Code beinhalten
         (z.B. Perl, PHP, teilweise auch Java)
●   Sichtweise 2: Wie wirken Kontrollstrukturen im Vergleich zu Methodenrufen?
     ●   Auf der niedrigsten Ebene (Prozessor) wirken Kontrollstrukturen ebenso wie
         Methodenaufrufe wie ein GOTO: Die Ausführung des Programms wird an einer
         anderen Adresse fortgesetzt.
     ●   Einziger Unterschied: Beim Methodenaufruf wird die Rücksprungadresse auf dem
         Stack gesichert
     ●   Der Zugriff auf Daten benötigt einen Schritt mehr, nämlich das Auslesen der
         Parameter von Stack
     ●   Auswirkungen zeigen hier vor allem komplexe Datenstrukturen, die Call-by-Value
         übergeben werden




                                                                                           45
Ist die zyklomatische Komplexität auch in
funktionalen Programmiersprachen einsetzbar?




                                               46
Ist die zyklomatische Komplexität auch in
                           funktionalen Programmiersprachen einsetzbar?

●   Prinzipiell: Ja, denn der Kontrollfluss existiert auch in funktionalen Sprachen
●   Schwierig ist die Definition der Kontrollstrukturen
     ●       If, Else etc. sind klar
     ●       Stellen Listenoperationen Kontrollstrukturen dar?
         1   val twoThree = List(2, 3)
         2   val oneTwoThree = 1 :: twoThree
         3
         4   myList.count(s => s.length == 4)
         5   myList.sort((s, t) => s.charAt(0).toLowerCase < t.charAt(0).toLowerCase)

●   Die zyklomatische Komplexität berücksichtigt Rekursion nicht – ein Methodenaufruf ist
    keine Kontrollstruktur




                                                                                            47
Was ist unter "Nichtäquivalenz der Interaktion" zu
                   verstehen?




                                                     48
Was ist unter "Nichtäquivalenz der Interaktion" zu verstehen?


●   Gegeben sind drei Klassen: P, Q und R
●   Metriken liefern für P und Q die gleichen Werte:   μ(Q)=μ( P)
●   Sowohl P als auch Q interagieren mit R
●   Metriken für P+R und Q+R muss nicht gleich sein




                                                                            49
Sollte man die Metrikwerte für jedes Projekt
           spezifisch normieren?




                                               50
Sollte man die Metrikwerte für jedes Projekt spezifisch normieren?


●   Nein!

●   Nicht für jedes Projekt, damit wäre kein Vergleich möglich
     ●   Metriken gewinnen an Wert durch Verwendung in verschiedenen Projekten
     ●   Erfahrungspotential der Entwickler ginge verloren
●   Aber: Technologische Einflüsse auf Metriken müssen berücksichtigt werden
     ●   Programmiersprachen
     ●   Konzepte (z.B. Aspektorientierte Programmierung, Lombok)
●   Wichtig ist, den Berechnungsweg der Metriken transparent zu machen




                                                                                 51
Wie viel Metriken sollte man in einem Projekt auf
               einmal betrachtet?




                                                    52
Wie viel Metriken sollte man in einem Projekt auf einmal betrachtet?


●   42

●   So wenig wie möglich, so viele wie nötig
●   Zu viele Metriken verwirren Entwickler und stören sich u. Ust. Gegenseitig
●   Aber: verschiedene Metriken beleuchten unterschiedliche Aspekte
●   Empfehlung für Objektorientierte Softwareentwicklung
     ●   Martin Metriken liefern Überblick
     ●   Chidamber & Kemerer liefern Detailsicht
     ●   Zyklomatische Komplexität für Methoden




                                                                                 53
Verwendung dieser Unterlagen


●   Wir stellen diese Unterlagen unter der Creative Commons Lizenz CC-BY-NC-SA zur allen
    am Thema Interessierten Verfügung.
●   Es ist erlaubt, die Unterlagen unter gleichen Bedingungen zu
     ●   kopieren
     ●   verteilen
     ●   übertragen und
     ●   adaptieren, wenn
●   die ursprünglichen Autoren genannt werden und
●   die Verwendung nicht zu kommerziellen Zwecken stattfindet.

●   Details zur Lizenz sind hier zu finden:
    http://creativecommons.org/licenses/by-nc-sa/3.0/




                                                                                           54

Weitere ähnliche Inhalte

Andere mochten auch

Andere mochten auch (6)

Technische Schulden - mit Notizen
Technische Schulden - mit NotizenTechnische Schulden - mit Notizen
Technische Schulden - mit Notizen
 
Vom Projektleiter zum Product Owner
Vom Projektleiter zum Product OwnerVom Projektleiter zum Product Owner
Vom Projektleiter zum Product Owner
 
Technische Schulden
Technische SchuldenTechnische Schulden
Technische Schulden
 
Agile Coach zu werden ist nicht schwer... - mit Notizen
Agile Coach zu werden ist nicht schwer... - mit NotizenAgile Coach zu werden ist nicht schwer... - mit Notizen
Agile Coach zu werden ist nicht schwer... - mit Notizen
 
Mehr Softwarequalität: Team-Cleancoding
Mehr Softwarequalität: Team-CleancodingMehr Softwarequalität: Team-Cleancoding
Mehr Softwarequalität: Team-Cleancoding
 
Softwarequalität - Architektur
Softwarequalität - ArchitekturSoftwarequalität - Architektur
Softwarequalität - Architektur
 

Mehr von Gerrit Beine

Auf Lesereise mit Frit und Fred
Auf Lesereise mit Frit und FredAuf Lesereise mit Frit und Fred
Auf Lesereise mit Frit und FredGerrit Beine
 
Mastering Cargo Cult
Mastering Cargo CultMastering Cargo Cult
Mastering Cargo CultGerrit Beine
 
Conway’s Law & Soziologie in der Software-Architektur
Conway’s Law & Soziologie in der Software-ArchitekturConway’s Law & Soziologie in der Software-Architektur
Conway’s Law & Soziologie in der Software-ArchitekturGerrit Beine
 
Beyond User Stories - Backlogs priorisieren, wenn es anspruchsvoll wird
Beyond User Stories - Backlogs priorisieren, wenn es anspruchsvoll wirdBeyond User Stories - Backlogs priorisieren, wenn es anspruchsvoll wird
Beyond User Stories - Backlogs priorisieren, wenn es anspruchsvoll wirdGerrit Beine
 
Mastering Cargo Cult - Dunning, Kruger & die Agile Bias Curve
Mastering Cargo Cult - Dunning, Kruger & die Agile Bias CurveMastering Cargo Cult - Dunning, Kruger & die Agile Bias Curve
Mastering Cargo Cult - Dunning, Kruger & die Agile Bias CurveGerrit Beine
 
Gut genug - Rahmenbedingungen für agile Architekturen
Gut genug - Rahmenbedingungen für agile ArchitekturenGut genug - Rahmenbedingungen für agile Architekturen
Gut genug - Rahmenbedingungen für agile ArchitekturenGerrit Beine
 
Beyond Agile – Ungewissheit mit der Real Option Theory meistern
Beyond Agile – Ungewissheit mit der Real Option Theory meisternBeyond Agile – Ungewissheit mit der Real Option Theory meistern
Beyond Agile – Ungewissheit mit der Real Option Theory meisternGerrit Beine
 
Backlog Priorisierung 2020: Wertmodelle & Simulationen von Intangibles zur Pr...
Backlog Priorisierung 2020: Wertmodelle & Simulationen von Intangibles zur Pr...Backlog Priorisierung 2020: Wertmodelle & Simulationen von Intangibles zur Pr...
Backlog Priorisierung 2020: Wertmodelle & Simulationen von Intangibles zur Pr...Gerrit Beine
 
Backlog Priorisierung mit Cost of Delay & Monte Carlo Simulationen
Backlog Priorisierung mit Cost of Delay & Monte Carlo SimulationenBacklog Priorisierung mit Cost of Delay & Monte Carlo Simulationen
Backlog Priorisierung mit Cost of Delay & Monte Carlo SimulationenGerrit Beine
 
Der hyperbolische Thread-Koeffizient
Der hyperbolische Thread-KoeffizientDer hyperbolische Thread-Koeffizient
Der hyperbolische Thread-KoeffizientGerrit Beine
 
Die Testedimaryp - Über die Antimonie des agilen Testens in der Praxis
Die Testedimaryp - Über die Antimonie des agilen Testens in der PraxisDie Testedimaryp - Über die Antimonie des agilen Testens in der Praxis
Die Testedimaryp - Über die Antimonie des agilen Testens in der PraxisGerrit Beine
 
Vom Projektleiter zum Product Owner
Vom Projektleiter zum Product OwnerVom Projektleiter zum Product Owner
Vom Projektleiter zum Product OwnerGerrit Beine
 
Die Product Owner Toolbox
Die Product Owner ToolboxDie Product Owner Toolbox
Die Product Owner ToolboxGerrit Beine
 
Agile Coach zu werden ist nicht schwer...
Agile Coach zu werden ist nicht schwer...Agile Coach zu werden ist nicht schwer...
Agile Coach zu werden ist nicht schwer...Gerrit Beine
 
Scaled, Distributed, Agile - Produktentwicklung auf neuen Wegen
Scaled, Distributed, Agile - Produktentwicklung auf neuen WegenScaled, Distributed, Agile - Produktentwicklung auf neuen Wegen
Scaled, Distributed, Agile - Produktentwicklung auf neuen WegenGerrit Beine
 
NTFS On Disk Structure
NTFS On Disk StructureNTFS On Disk Structure
NTFS On Disk StructureGerrit Beine
 
Semistrukturierte Daten in relationalen Datenbanken
Semistrukturierte Daten in relationalen DatenbankenSemistrukturierte Daten in relationalen Datenbanken
Semistrukturierte Daten in relationalen DatenbankenGerrit Beine
 
Volltextsuchen in RDBMS (2004)
Volltextsuchen in RDBMS (2004)Volltextsuchen in RDBMS (2004)
Volltextsuchen in RDBMS (2004)Gerrit Beine
 

Mehr von Gerrit Beine (20)

Auf Lesereise mit Frit und Fred
Auf Lesereise mit Frit und FredAuf Lesereise mit Frit und Fred
Auf Lesereise mit Frit und Fred
 
Mastering Cargo Cult
Mastering Cargo CultMastering Cargo Cult
Mastering Cargo Cult
 
Conway’s Law & Soziologie in der Software-Architektur
Conway’s Law & Soziologie in der Software-ArchitekturConway’s Law & Soziologie in der Software-Architektur
Conway’s Law & Soziologie in der Software-Architektur
 
Beyond User Stories - Backlogs priorisieren, wenn es anspruchsvoll wird
Beyond User Stories - Backlogs priorisieren, wenn es anspruchsvoll wirdBeyond User Stories - Backlogs priorisieren, wenn es anspruchsvoll wird
Beyond User Stories - Backlogs priorisieren, wenn es anspruchsvoll wird
 
Mastering Cargo Cult - Dunning, Kruger & die Agile Bias Curve
Mastering Cargo Cult - Dunning, Kruger & die Agile Bias CurveMastering Cargo Cult - Dunning, Kruger & die Agile Bias Curve
Mastering Cargo Cult - Dunning, Kruger & die Agile Bias Curve
 
Gut genug - Rahmenbedingungen für agile Architekturen
Gut genug - Rahmenbedingungen für agile ArchitekturenGut genug - Rahmenbedingungen für agile Architekturen
Gut genug - Rahmenbedingungen für agile Architekturen
 
Beyond Agile – Ungewissheit mit der Real Option Theory meistern
Beyond Agile – Ungewissheit mit der Real Option Theory meisternBeyond Agile – Ungewissheit mit der Real Option Theory meistern
Beyond Agile – Ungewissheit mit der Real Option Theory meistern
 
Backlog Priorisierung 2020: Wertmodelle & Simulationen von Intangibles zur Pr...
Backlog Priorisierung 2020: Wertmodelle & Simulationen von Intangibles zur Pr...Backlog Priorisierung 2020: Wertmodelle & Simulationen von Intangibles zur Pr...
Backlog Priorisierung 2020: Wertmodelle & Simulationen von Intangibles zur Pr...
 
Backlog Priorisierung mit Cost of Delay & Monte Carlo Simulationen
Backlog Priorisierung mit Cost of Delay & Monte Carlo SimulationenBacklog Priorisierung mit Cost of Delay & Monte Carlo Simulationen
Backlog Priorisierung mit Cost of Delay & Monte Carlo Simulationen
 
Der hyperbolische Thread-Koeffizient
Der hyperbolische Thread-KoeffizientDer hyperbolische Thread-Koeffizient
Der hyperbolische Thread-Koeffizient
 
Broken by Design
Broken by DesignBroken by Design
Broken by Design
 
Die Testedimaryp - Über die Antimonie des agilen Testens in der Praxis
Die Testedimaryp - Über die Antimonie des agilen Testens in der PraxisDie Testedimaryp - Über die Antimonie des agilen Testens in der Praxis
Die Testedimaryp - Über die Antimonie des agilen Testens in der Praxis
 
Vom Projektleiter zum Product Owner
Vom Projektleiter zum Product OwnerVom Projektleiter zum Product Owner
Vom Projektleiter zum Product Owner
 
Antifragilität
AntifragilitätAntifragilität
Antifragilität
 
Die Product Owner Toolbox
Die Product Owner ToolboxDie Product Owner Toolbox
Die Product Owner Toolbox
 
Agile Coach zu werden ist nicht schwer...
Agile Coach zu werden ist nicht schwer...Agile Coach zu werden ist nicht schwer...
Agile Coach zu werden ist nicht schwer...
 
Scaled, Distributed, Agile - Produktentwicklung auf neuen Wegen
Scaled, Distributed, Agile - Produktentwicklung auf neuen WegenScaled, Distributed, Agile - Produktentwicklung auf neuen Wegen
Scaled, Distributed, Agile - Produktentwicklung auf neuen Wegen
 
NTFS On Disk Structure
NTFS On Disk StructureNTFS On Disk Structure
NTFS On Disk Structure
 
Semistrukturierte Daten in relationalen Datenbanken
Semistrukturierte Daten in relationalen DatenbankenSemistrukturierte Daten in relationalen Datenbanken
Semistrukturierte Daten in relationalen Datenbanken
 
Volltextsuchen in RDBMS (2004)
Volltextsuchen in RDBMS (2004)Volltextsuchen in RDBMS (2004)
Volltextsuchen in RDBMS (2004)
 

Softwarequalität - Metriken

  • 1. Die Macht der Zahlen Source Code Metriken Prof. Dr. Wolfgang Golubski Gerrit Beine, M.Sc. golubski@fh-zwickau.de mail@gerritbeine.com 1
  • 4. McCabes zyklomatische Komplexität ● Literatur: A Complexity Measure; Thomas J. McCabe ● IEEE Transactions on Software Engineering, Vol. SE-2, No.4, December 1976 ● http://www.literateprogramming.com/mccabe.pdf ● Die zyklomatische Komplexität basiert auf der Graphentheorie ● Ursprünglich für FORTRAN erdacht ● Auf alle strukturierten und prozeduralen Sprachen anwendbar ● Entscheidungen im Programm werden zu Knoten im Graph ● Programmlogik wird als Kanten des Graphs interpretiert v (G)=e−n+2∗p ● Zyklomatische Komplexität: ● e = edges, Kanten im Graph ● n = nodes, Knoten im Graph ● p = parts, (unabhängige) Teile des Graph 4
  • 5. Algorithmische Ermittlung der zyklomatischen Komplexität ● Theorem: v(G) ist gleich der Anzahl der A unabhängigen Zyklen des Graph. ● Ermittlung durch Zweigüberdeckung: B C D ● Übertragung des Graphen in einen Baum ● Jeder Pfad im Graph entspricht E einem Pfad im Baum ● Anwendung der Tiefensuche A F ● Es werden nur Knoten untersucht, die noch nicht besucht wurden B C D ● Wurde ein Knoten besucht, ist ein neuer unabhängiger Kreis entdeckt E F C ● Vorgehen liefert gleichzeitig Testfälle für den Graph B A F A 5
  • 6. Anwendung der zyklomatischen Komplexität auf objektorienten Code ● Methodenbasiert ● Es werden die Kontrollstrukturen innerhalb von Methoden untersucht ● Mögliche Ergebnisse: ● v(G) für konkrete Methode, avg v(G) pro Methode / Klasse / Package (sinnfrei) ● Prozessbasiert ● Sämtliche für einen Prozess relevanten Methoden werden als unabhängige Teilgraphen (Components) betrachtet ● e sind die Kanten der Kontrollstrukturgraphen aller Methoden ● n sind die Knoten der Kontrollstrukturgraphen aller Methoden ● p ist die Anzahl der beteiligten Methoden ● Berechnung ist aufwändig (abhängig von Kopplung) ● Algorithmus liefert aber sehr interessante Aussagen u.a. über die Gesamtkomplexität von Prozessen 6
  • 8. Die Halstead-Metriken ● Literatur: Elements of Software Science; Maurice H. Halstead ● Elsevier Science Inc., New York, 1977 ● Halsteadt definierte eine Reihe von Metriken zur Komplexitäts- und Aufwandsschätzung ● Program vocabulary (n) ● Program length (N) ● Calculated program length ● Program volume (V) ● Program difficulty level (D) ● Program level (L) ● Effort to implement (E) ● Time to implement (T) ● Number of delivered bugs (B) 8
  • 9. Berechnung der Halstead-Metriken ● Unique Operators and Operands: n1, n2 ● Total amount of Operators and Operands: N1, N2 ● Program vocabulary: n=n1+n2 ● Program length: N =N1+N2 ● Calculated program length: ̂ N =n1∗log 2 (n1)+n2∗log 2 (n2) ● Program volume: V =N∗log2 (n) N1 n2 ● Program difficulty level: D=( )∗( ) 2 2 Program level: 1 ● L= D ● Effort to implement: E=V ∗D E ● Time to implement: T= 18 2 ● Number of delivered bugs: E3 V B= oder neu : B= 3000 3000 9
  • 10. Kritik an Halsteadts Metriken ● Definition von Operator und Operand ist nicht festgelegt ● Fenton, N., Software Measurement: A Necessary Scientific Basis. In IEEE Transactions on Software Engineering, 1004, vol. 20(3), pp. 199-206. ● Halsteads Metriken liefern keine Aussagen zur Komplexität, werden aber oft dafür herangezogen ● Al-Qutaish, R.E., and Abran, A., An analysis of the design and definitions of Halstead’s metrics, In 15th Int. Workshop on Software Measurement, 2005, pp. 337-352. ● Die Unklarheit von Halsteads Definitionen führt zu verschiedenen Interpretationen ● Die Anwendbarkeit auf moderne Programmiersprachen ist nicht festgelegt ● Beser, N., Foundations and experiments in software science. In Selected Papers of the 1982 ACM SIGMETRICS Workshop on Software Metrics: Part 2, 1982, pp. 48-72. und Davies, G., and Tan, A., A note on metrics of Pascal programs. In ACM SIGPLAN Notices, 1987, vol. 22(8), pp. 39-44. ● Die Formel für N überschätzt die Länge kleiner Programme und unterschätzt die Länge großer Programme 10
  • 12. Der Maintainability Index ● Literatur: Oman, P., Hagemeister, J.: Metrics for assessing Software System Maintainability ● IEEE Int. Conference on Software Maintenance, 1994, S. 337 ● Zusammenhang zwischen Codeeigenschaften und Wartungsaufwand ● Basiert auf anderen Metriken ● Aufwand nach Halstead (E) ● Zyklomatische Komplexität nach McCabe (G) ● Modulgröße (LOC) ● In einer Überarbeitung kam noch hinzu ● Kommentierungsgrad (CMT) prozentualer Anteil an den LOC ● Halstead-Volumen (V) alternativ zum Aufwand nach Halstead (E) 12
  • 13. Der Maintainability Index ● 1992: ursprüngliche Formel MI =171−5,2∗ln (E)−0,23∗ln (G)−16,2∗ln (LOC ) ● 1994: Berücksichtigung von Kommentaren MI =171−5,2∗ln (V )−0,23∗ln (G)−16,2∗ln (LOC )+50∗sin √ 2,4∗CMT ● Interpretation ● MI > 85: gute Wartbarkeit ● 65<MI<85: mittlere Wartbarkeit ● MI<65: schlechte Wartbarkeit ● Normalisierter MI von Microsoft MI =MAX (0,(171−5,2∗ln (V )−0,23∗ln (G)−16,2∗ln (LOC ))∗100/171) ● Interpretation ● 0-9 = Rot ● 10-19 = Gelb ● 20-100 = Grün 13
  • 14. Kritik am Maintainability Index ● Korrektheit von MI wurde nur über Korrelation mit subjektivem Empfinden von Wartbarkeits-Experten geprüft (0,81-0,93) ● Reduzieren von Software auf einen einzigen Wert ist nur als Trend aussagekräftig ● Beschränkung auf spezifische Metriken reduziert die Anwendbarkeit auf moderne Programmiersprachen ● Sneed, H.: “Software muss messbar werden”, Zeitschrift für Information Management, Nr. 4, 1991, S. 39 ● Nur 40% der Wartungskosten werden von MI tangiert, der Rest teilt sich zwischen Wartungspersonal und Wartungsumgebung auf 14
  • 15. Die Robert C. Martin-Metriken 15
  • 16. Die Robert C. Martin-Metriken ● Literatur: OO Design Quality Metrics; An Analysis of Dependencies; By Robert Martin ● http://www.objectmentor.com/resources/articles/oodmetrc.pdf ● Die Martin-Metriken zielen auf folgende Clean Code Prinzipien ab ● Single Responsibility Principle (SRP) ● Separation of Concerns (SOC) ● Interface Segregation Principle (ISP) ● Dependecy Inversion Principle (DIP) ● Information Hiding Principle (IHP) ● Open Closed Principle (OCP) 16
  • 17. Instabilität ● Ca: Afferent Couplings: Anzahl der Klassen außerhalb der Kategorie, die von Klassen innerhalb der Kategorie abhängen – eingehende Abhängigkeiten ● Ce: Efferent Couplings: Anzahl der Klassen außerhalb der Kategorie, von denen Klassen innerhalb der Kategorie abhängen – ausgehende Abhängigkeiten ● Eselsbrücke: Inversion Ca = eingehend, Ce = ausgehend Ce ● Instability: I = , I ∈[0,1]; ∑ Ce= ∑ Ca Ca+Ce Kategorien Kategorien ● Keine ausgehenden Abhängigkeiten: Hohe Stabilität, Tendenz ist I = 0 ● Keine eingehenden Abhängigkeiten: Hohe Instabilität, Tendenz ist I = 1 ● Grenzwertbetrachtungen: Ce Ce Ce Ce lim =0 lim =1 lim =1 lim =0 Ce → 0 Ca+Ce Ce → ∞ Ca+Ce Ca → 0 Ca+Ce Ca →∞ Ca+Ce 17
  • 18. Instabilität ● Hohe Stabilität (I nahe 0) ist erforderlich für ● System-Kerne Komponenten, um die eine Software herum gebaut wird. ● Datenmodelle Ein gutes Beispiel sind EJB3 Entities. Diese sollten von keinen anderen Komponenten einer Software abhängen. ● Hohe Instabilität (I nahe 1) entsteht bei ● Implementierung von externen Schnittstellen Als Beispiel kann die Implementierung eines WebService dienen, der Funktionalität nach außen zur Verfügung stellt. Von solchen Komponenten darf innerhalb des Systems nichts abhängen. ● komplexen User Interfaces User Interfaces führen oftmals viele Komponenten zusammen. Somit entstehen hohe Werte für ausgehende Abhängigkeiten. 18
  • 19. Instabilität ● Keine Pakete mit I=0 → ● Kein Systemkern ● Zyklische Abhängigkeiten vorhanden ● Viele Pakete mit I=1 → ● Hohe Wartungsaufwände bei kleinen Änderungen ● Prinzip: Je mehr Pakete mit höherer Instabilität, desto größer ist der Domino-Effekt bei Änderungen. ● Ziel: Möglichst viele stabile Pakete. Software neigt leider dazu, sich entgegengesetzt zu entwicklen. 19
  • 20. Abstraktion ● NoAC: Number of Abstract Classes: Alle abstrakten Klassen eines Paketes ● NoCC: Number of Concrete Classes: Alle nicht abstrakten Klassen eines Paketes ● NoI: Number of Interfaces: Alle Schnittstellen eines Paketes ● NoC: Number of Classes = NoAC+NoCC: Alle Klassen eines Paketes Abstractness A= NoAC+ NoI NoACI ● = =, A ∈[0, 1] NoCC+NoAC+NoI NoCI ● Keine abstrakten Klassen und Schnittstellen: Niedrige Abstraktion, Tendenz ist A = 0 ● Ausschließlich abstrakte Klassen und Schnittstellen: Hohe Abstraktion, Tendenz ist A = 1 ● Grenzwertbetrachtungen: NoAC+NoI NoAC+NoI lim =0 lim =1 NoAC+ NoI → 0 NoCC+NoAC+NoI NoAC+ NoI → ∞ NoCC+NoAC+NoI NoAC+NoI NoAC+NoI lim =1 lim =0 NoCC →0 NoCC+ NoAC+NoI NoCC →∞ NoCC+NoAC+NoI 20
  • 21. Abstraktion ● Keine Pakete mit A=1 → ● Schnittstellen nicht einzeln distributierbar ● Viele Pakete mit A=0 → ● Erweiterungen (OCP) nicht möglich ● Prinzip: Abstrakte Pakete sind entsprechend des OCP leichter zu erweitern als nicht abstrakte Pakete. ● Ziel: Definierte abstrakte Pakete, um Schnittstellen zu separieren. Gute Abstraktion benötigt viel Zeit. 21
  • 22. Distanz ● Pakete sollten ausschließlich von stabileren Paketen (idealerweise auch abstrakteren Paketen) abhängen. (ISP) ● Das ist die Grundlage für Inversion of Control bzw. Dependency Injection ● Zusammenhänge zwischen Abstraktion und Instabilität ● Abstrakte Pakete (A=1) sollten stabil sein (I=0), d.h. keine ausgehenden Abhängigkeiten besitzen. Damit sind sie offen für Erweiterungen und geschlossen gegenüber Modifikationen. (OCP) ● Instabile Pakete (I=1) sollten nicht abstrakt (A=0) sein. Sie sind nicht mehr erweiterbar, unterliegen aber eine hohe Änderungswahrscheinlichkeit. ● Pakete mit balancierter Abstraktion (A=0,5) und Instabilität (I=0,5) sind noch teilweise erweiterbar, unterliegen allerdings schon einer gewissen Änderungswahrscheinlichkeit. ● Abstraktion und Instabilität sollten ausbalanciert sein. 22
  • 23. Distanz ● Balance zwischen A und I ergibt einen Graphen, der folgender Formel genügt: ● Distance: Dn=∣A+I−1∣, Dn∈[0,1] ● Pakete, die sich nahe der Main Sequence befinden, sind ausbalanciert. ● Je weiter ein Paket von der Main Sequence entfernt ist, desto schwieriger wird seine Verwendung (Area of Uselessness bei A=1 und I=1) oder seine Wartung (Area of Pain bei A=0 und I=0) ● Ziel: Optimale Pakete befinden sich an einem der Endpunkte der Main Sequence, die Entfernung zur Main Sequence (=Distanz) Quelle: http://www.objectmentor.com/resources/articles/oodmetrc.pdf sollte minimal sein. 23
  • 24. Einige ausgewählte Metriken Chidamber & Kemerers OO-Metriken 24
  • 25. Chidamber & Kemerers OO-Metriken ● Literatur: S. R. Chidamber, C.F. Kemerer, A Metrics Suite for Object Oriented Design ● IEEE Transactions on Software Engineering, 20(6), 1994, S. 476-493 ● Sammlung von Metriken zur Bewertung objektorientierter Systeme ● Weighted Method Count (WMC) ● Coupling Between Object Classes (CBO) ● Depth of Inheritance Tree (DIT) ● Number of Children (NOC) ● Response For a Class (RFC) ● Lack of Cohesion in Methods (LCOM) 25
  • 26. Weighted Method Count (WMC) / Coupling Between Object Classes (CBO) WMC CBO n ● Formel: WMC=∑ c i ● Anzahl der Klassen, die von einer Klasse i=1 ● Als Komplexitätsfunktion kann z.B. die benutzt werden zyklomatische Komplexität dienen ● Ein hoher Wert für CBO deutet auf ● Kann als Wartungsmaß dienen, da eine Änderungsaufwände hin größere Anzahl komplexer Methoden ● Entspricht dem Ce der Martin-Metrik auf höhere Wartungsaufwände verursachen Klassenebene kann ● Je höher der Wert von CBO, desto höher ● Bei Vererbung führen hohe Werte von der Wert der Instability WMC zu engen Kopplungen ● Fokus auf Struktur ● Kritik: Attribute von Klassen werden nicht berücksichtigt ● Clean-Code-Prinzip: SRP Single Responsibility Principle 26
  • 27. Number of Children (NOC) / Depth of Inheritance Tree (DIT) NOC DIT ● Maß für die Anzahl unmittelbar ● Tiefe der Verbungshierarchie einer Klasse abgeleiteter Klassen ● Anzahl geerbter Eigenschaften steigt mit ● Ein hoher Wert für NOC ist ein Indiz für höherer DIT häufige Wiederverwendung ● Klassen mit hoher DIT können nicht ● Änderungsaufwand für Klassen mit isoliert betrachtet werden hohem Wert für NOC ist hoch ● Als Maximalwert für den DIT wird im ● Testaufwand für Klassen mit hohem NOC Allgemeinen 7 angesehen ist sehr hoch ● Clean-Code-Prinzip: FCoI ● Clean-Code-Prinzip: FCoI Favour Composition over Inheritance Favour Composition over Inheritance ● Clean-Code-Prinzip: IHP ● Clean-Code-Prinzip: OCP Information Hiding Principle Open Closed Principle ● Clean-Code-Prinzip: OCP Open Closed Principle 27
  • 28. Response For a Class (RFC) / Lack of Cohesion in Methods (LCOM) RFC LCOM ● Response Set: Alle Methoden einer Klasse ● Maß für die gemeinsame Nutzung von und die von den Methoden benutzten Attributen einer Klasse durch ihre Methoden anderer Klassen Methoden ● Hoher Wert für RFC deutet auf schlechtes ● Ein hoher Wert von LCOM weist auf Design hinsichtlich der Separation of schlechtes Design im Sinne der Concerns hin Separation of Concerns hin ● RFC und CBO korrellieren im Allgemeinen ● Klassen mit hohem LCOM sollten geteilt ● Fokus auf Interaktion werden ● Clean-Code-Prinzip: SRP ● Clean-Code-Prinzip: SRP Single Responsibility Principle Single Responsibility Principle ● Clean-Code-Prinzip: Tell, don't ask 28
  • 30. Das Problem mit der Kopplung 30
  • 31. Das Problem mit der Kopplung ● Reale Anwendung ● Anwendung enthält rund 35 Entitäten ● Durchschnittliche Kopplung liegt bei mehr als 30! ● Wartung nahezu unmöglich ● Unglücklicherweise sagt der Maintainability Index: 165 31
  • 32. Welche Metriken sind wichtig und weit verbreitet? 32
  • 33. Welche Metriken sind wichtig und weit verbreitet? ● Am weitesten verbreitet sind mit Sicherheit die Metrik der Lines of Code, die zyklomatische Komplexität und der Maintainability Index ● Die Verbreitung sagt aber nichts über den Nutzen einer Metrik in einem konkreten Projekt aus ● Oft werden weit verbreitete Metriken völlig falsch angewendet und damit mehr Schaden produziert, als Nutzen geschaffen ● Wichtig sind immer genau die Metriken, die die Antworten auf die Fragen liefern, die sich aus dem Ziel eines Projektes ergeben ● Es sollte nie nur eine Metrik herangezogen werden, sondern idealerweise Metriken, die orthogonal zueinander messen ● Gut ist auch der Ansatz, immer zwei Metriken zu nutzen, die die gleiche Frage beantworten: Ist die Antwort identisch, ist sie mit höherer Wahrscheinlichkeit richtig 33
  • 34. Welche Tools können verwendet werden? 34
  • 35. Welche Tools können verwendet werden? ● Unter Java ● JDepend: Martin ● DependencyFinder & OOMetrics: Martin, Chidamber & Kemerer ● PMD: Zyklomatische Komplexität, NPath ● CheckStyle: Zyklomatische Komplexität, NPath ● Unter PHP ● PHP Mess Detector: Zyklomatische Komplexität, NPath ● PhpDepend: Martin ● Unter .NET ● Dependometer: Chidamber & Kemerer 35
  • 36. Wie würde ein ausbalanciertes Klassendesign aussehen (z.B. I = 0.5 und A=0.5)? 36
  • 37. Wie würde ein ausbalanciertes Klassendesign aussehen? ● Balanciert ist das Design nicht nur bei I=0,5 und A=0,5, sondern entlang der gesamten Main Sequence ● Der Idealzustand ist, dass jedes Paket entweder bei I=1 und A=0 oder I=0 und A=1 anzusiedeln ist. ● Praktisch ist das nicht zu realisieren (im Sinne einer wirtschaftlichen Entwicklung), allerdings ist es nicht das Ziel, I=0,5 und A=0,5 zu erreichen. ● Das Abstract-Stable-Principle besagt, dass ein Paket so stabil wie abstrakt sein soll: A ≃1−I 37
  • 38. Wie würde ein ausbalanciertes Klassendesign aussehen? IF Ca Ce I A Bild 1 M E Model 2 0 0 0 IM Interfaces 1 1 0,5 1 Implementierung 0 3 1 0 Exceptions 1 0 0 0 IF Bild 2 Model 2 0 0 0 M E Interfaces 1 2 0,66 1 IM Implementierung 0 3 1 0 Exceptions 2 0 0 0 38
  • 39. Wie würde ein ausbalanciertes Klassendesign aussehen? IF Ca Ce I A Bild 3 M E Model 3 0 0 0 IM Interfaces 2 1 0,33 1 Implementierung 0 3 1 0 Exceptions 2 0 0 0 IF Model 2 1 0,33 0 Interfaces 1 1 0,5 1 M E Implementierung 0 5 1 0 IM Exceptions 1 0 0 0 39
  • 40. Wann ist es sinnvoll die Komplexität zu verteilen, bereits während der Programmierung oder erst beim Refactoring? 40
  • 41. Wann ist es sinnvoll die Komplexität zu verteilen, bereits während der Programmierung oder erst beim Refactoring? ● Refactoring ist Programmierung ● Im Sinne des Test Driven Development ● Zunächst Funktionalität realisieren ● Danach Komplexität reduzieren 41
  • 42. Stellt die "Auslagerung" der Komplexität (z.B. einer Methode) nicht einen Widerspruch hinsichtlich der Wartbarkeit dar? 42
  • 43. Stellt die "Auslagerung" der Komplexität (z.B. einer Methode) nicht einen Widerspruch hinsichtlich der Wartbarkeit dar? ● Frage wurde bezüglich der zyklomatischen Komplexität gestellt ● Widersprucht besteht nicht im Sinne der Separation of Concerns ● Inhaltlich verschiedenes voneinander Trennen schafft Übersichtlichkeit ● In objektorientierten Sprachen Polymorphismus als Ersatz für Kontrollstrukturen verwenden führt zum Verschwinden von Knoten aus dem Graph ● Polymorphe Methoden bearbeiten jeweils nur einen konkreten Typ: Daraus resultierende Vereinfachung leuchtet ein :-) 43
  • 44. Wie wirkt sich die Verteilung der Komplexität auf das Laufzeitverhalten (und den Speicherverbrauch) von Programmen aus? 44
  • 45. Wie wirkt sich die Verteilung der Komplexität auf das Laufzeitverhalten (und den Speicherverbrauch) von Programmen aus? ● Im besten Falle positiv, manchmal gar nicht und hin und wieder negativ. ● Sichtweise 1: Dynamisches Laden von Programmteilen ● Es werden nur die Klassen überhaupt geladen, die auszuführenden Code beinhalten (z.B. Perl, PHP, teilweise auch Java) ● Sichtweise 2: Wie wirken Kontrollstrukturen im Vergleich zu Methodenrufen? ● Auf der niedrigsten Ebene (Prozessor) wirken Kontrollstrukturen ebenso wie Methodenaufrufe wie ein GOTO: Die Ausführung des Programms wird an einer anderen Adresse fortgesetzt. ● Einziger Unterschied: Beim Methodenaufruf wird die Rücksprungadresse auf dem Stack gesichert ● Der Zugriff auf Daten benötigt einen Schritt mehr, nämlich das Auslesen der Parameter von Stack ● Auswirkungen zeigen hier vor allem komplexe Datenstrukturen, die Call-by-Value übergeben werden 45
  • 46. Ist die zyklomatische Komplexität auch in funktionalen Programmiersprachen einsetzbar? 46
  • 47. Ist die zyklomatische Komplexität auch in funktionalen Programmiersprachen einsetzbar? ● Prinzipiell: Ja, denn der Kontrollfluss existiert auch in funktionalen Sprachen ● Schwierig ist die Definition der Kontrollstrukturen ● If, Else etc. sind klar ● Stellen Listenoperationen Kontrollstrukturen dar? 1 val twoThree = List(2, 3) 2 val oneTwoThree = 1 :: twoThree 3 4 myList.count(s => s.length == 4) 5 myList.sort((s, t) => s.charAt(0).toLowerCase < t.charAt(0).toLowerCase) ● Die zyklomatische Komplexität berücksichtigt Rekursion nicht – ein Methodenaufruf ist keine Kontrollstruktur 47
  • 48. Was ist unter "Nichtäquivalenz der Interaktion" zu verstehen? 48
  • 49. Was ist unter "Nichtäquivalenz der Interaktion" zu verstehen? ● Gegeben sind drei Klassen: P, Q und R ● Metriken liefern für P und Q die gleichen Werte: μ(Q)=μ( P) ● Sowohl P als auch Q interagieren mit R ● Metriken für P+R und Q+R muss nicht gleich sein 49
  • 50. Sollte man die Metrikwerte für jedes Projekt spezifisch normieren? 50
  • 51. Sollte man die Metrikwerte für jedes Projekt spezifisch normieren? ● Nein! ● Nicht für jedes Projekt, damit wäre kein Vergleich möglich ● Metriken gewinnen an Wert durch Verwendung in verschiedenen Projekten ● Erfahrungspotential der Entwickler ginge verloren ● Aber: Technologische Einflüsse auf Metriken müssen berücksichtigt werden ● Programmiersprachen ● Konzepte (z.B. Aspektorientierte Programmierung, Lombok) ● Wichtig ist, den Berechnungsweg der Metriken transparent zu machen 51
  • 52. Wie viel Metriken sollte man in einem Projekt auf einmal betrachtet? 52
  • 53. Wie viel Metriken sollte man in einem Projekt auf einmal betrachtet? ● 42 ● So wenig wie möglich, so viele wie nötig ● Zu viele Metriken verwirren Entwickler und stören sich u. Ust. Gegenseitig ● Aber: verschiedene Metriken beleuchten unterschiedliche Aspekte ● Empfehlung für Objektorientierte Softwareentwicklung ● Martin Metriken liefern Überblick ● Chidamber & Kemerer liefern Detailsicht ● Zyklomatische Komplexität für Methoden 53
  • 54. Verwendung dieser Unterlagen ● Wir stellen diese Unterlagen unter der Creative Commons Lizenz CC-BY-NC-SA zur allen am Thema Interessierten Verfügung. ● Es ist erlaubt, die Unterlagen unter gleichen Bedingungen zu ● kopieren ● verteilen ● übertragen und ● adaptieren, wenn ● die ursprünglichen Autoren genannt werden und ● die Verwendung nicht zu kommerziellen Zwecken stattfindet. ● Details zur Lizenz sind hier zu finden: http://creativecommons.org/licenses/by-nc-sa/3.0/ 54