Codemetriken

Die Kraft der Code-Metriken mit CppDepend freisetzen

Um Metriken zu lernen, können Sie drucken: Placemat-Visualisierungsexperte von Stuart Celarier MVP (Corillian) oder Sie können dies drucken Metriken-Spickzettel von Frank-Leonardo Quednau.

  • 8 Metriken auf Anwendung: NbLinesOfCode, NbLinesOfComment, PercentageComment, NbProjects, NbNamespaces, NbTypes, NbMethods, NbFields
  • 14 Metriken auf Projekte: NbLinesOfCode, NbLinesOfComment, PercentageComment, NbNamespaces, NbTypes, NbMethods, NbFields, Assembly level, Afferent coupling (Ca), Efferent coupling (Ce), Relational Cohesion(H), Instability (I), Abstractness (A), Distance from main sequence (D)
  • 9 Metriken auf Namespaces: NbLinesOfCode, NbLinesOfComment, PercentageComment, NbTypes, NbMethods, NbFields, Project level, Afferent coupling at namespace level (NamespaceCa), Efferent coupling at namespace level (NamespaceCe)
  • 16 Metriken auf Typen: NbLinesOfCode, NbLinesOfComment, PercentageComment, NbMethods, NbFields, Type level, Type rank, Afferent coupling at type level (TypeCa), Efferent coupling at type level (TypeCe), LCOM, LCOM HS, Cyclomatic Complexity, Size of instance, ABC, NOC, DIT
  • 11 Metriken auf Methoden: NbLinesOfCode, NbLinesOfComment, PercentageComment, Method level, Method rank, MethodCa, MethodCe, Cyclomatic Complexity, NbParameters, NbVariables, NbOverloads
  • 2 Metriken auf Felder: Instanzgröße, FieldCa
  • 11 Halstead-Metriken: Total Operators, Total Operands, Distinct Operators, Distinct Operands, Halstead Program Length, Halstead Program Volume, Halstead Program Level, Halstead Program Difficulty, Halstead Programming Effort, Halstead Programming Time, Halstead Intelligent Content

Metriken der technischen Schuld

Seit Version 2017.1.0 bietet CppDepend intelligente Schätzung der technischen Schuld einer Codebasis.

Grundsätzlich erzeugt jede CppDepend-Code-Regel Issues, und für jedes Issue schätzen anpassbare C#-Formeln Kosten der Behebung diese Probleme in Personenzeit.

Diese Behebungskosten können gesehen werden als Schuld das Team besitzt: Solange das Problem nicht behoben ist, ist die Schuld nicht zurückgezahlt, und sie verursacht Zinsen in Form von Entwicklungsreibung. Die technische Schuld der Codebasis ist die Summe all dieser Schuldenschätzungen.

Die technische Schuld kann gesehen werden als Mutter aller Codemetriken.

  • Alle anderen Codemetriken – Codezeilen, Komplexität, Codeabdeckung, Kopplung ... – können über Coderegeln mit Schwellenwerten genutzt werden. Die Regeln erzeugen Probleme bei Verletzungen von Codemetrik-Schwellenwerten.
  • Und für jedes Problem können wir schätzen: Kosten der Behebung in Bezug auf Personenzeit.
  • Für jedes Problem können wir außerdem schätzen: Schweregrad in Bezug auf Personenzeit pro Jahr, die durch das nicht behobene Problem verbraucht wird Konsequenzen.

Unten finden Sie die technischen Details zu jeder von CppDepend unterstützten Code-Metrik. Die Schätzung der technischen Schulden hat ihre eigene Dokumentationsseite.

Codemetrik-Visualisierung

CppDepend wird mit einem Dashboard geliefert, um alle Anwendungsmetriken schnell zu visualisieren. Das Dashboard ist sowohl in der Visual Studio-Erweiterung als auch im Bericht verfügbar.

Für jede Metrik zeigt das Dashboard den Diff seit der Baseline. Es zeigt auch, ob der Metrikwert besser (grün) oder schlechter (rot) wird.

Jeder Wert ist anklickbar, um tiefer einzusteigen. Ein Klick auf die Anzahl der Typen listet zum Beispiel alle Typen der Codebasis.

CppDepend-Codemetrik-Dashboard

CppDepend bietet zudem eine spezielle Metrikvisualisierung über eine farbige Treemap. Eine solche Visualisierung ist besonders nützlich, um die Testabdeckung von Methoden oder Klassen Ihrer Codebasis zu durchsuchen.

CppDepend-Codemetrik-Treemap

Metriken zur Anwendung

NbLinesOfCode

Beachten Sie, dass die LOC eines Typs die Summe der LOC seiner Methoden ist, die LOC eines Namespaces die Summe der LOC seiner Typen, die LOC eines Projekts die Summe der LOC seiner Namespaces und die LOC einer Anwendung die Summe der LOC ihrer Projekte.

  • Abstrakte Methoden und Enumerationen haben eine LOC von 0. Bei der LOC-Berechnung wird nur konkreter Code berücksichtigt, der tatsächlich ausgeführt wird.
  • Deklarationen von Namespaces, Typen, Feldern und Methoden gelten nicht als Codezeilen, da ihnen keine Sequenzpunkte entsprechen.

Empfehlungen: Methoden mit NbLinesOfCode über 20 sind schwer zu verstehen und zu warten.

NbLinesOfComment

Definiert für Anwendung, Projekte, Namespaces, Typen, Methoden.

Empfehlungen: Diese Metrik eignet sich nicht zur Bewertung der Quellcodequalität. Wir bevorzugen die Metrik PercentageComment.

PercentageComment

Definiert für Anwendung, Projekte, Namespaces, Typen, Methoden.

PercentageComment = 100*NbLinesOfComment / ( NbLinesOfComment + NbLinesOfCode)

Empfehlungen: Code mit einem Kommentaranteil unter 20 % sollte stärker kommentiert werden. Übermäßig kommentierter Code (>40 %) ist jedoch nicht unbedingt ein Segen, da er als Beleidigung der Intelligenz des Lesers betrachtet werden kann.

NbProjects

Definiert für Anwendung – Die Anzahl der Projekte.

NbNamespaces

Definiert für Anwendung und Projekte. Die Anzahl der Namespaces. Der anonyme Namespace zählt als einer. Wenn ein Namespace über N Projekte definiert ist, zählt er als N. In Framework-Projekten deklarierte Namespaces werden nicht berücksichtigt.

NbTypes

Definiert für Anwendung, Projekte, Namespaces. Die Anzahl der Typen. Ein Typ kann eine abstrakte oder konkrete Klasse, eine Struktur oder eine Enumeration sein.

NbMethods

Definiert für Anwendung, Projekte, Namespaces, Typen. Die Anzahl der Methoden. Eine Methode kann eine abstrakte, virtuelle oder nicht-virtuelle Methode sein, eine in einer Schnittstelle deklarierte Methode, ein Konstruktor, ein Klassenkonstruktor, ein Finalizer, ein Property-/Indexer-Getter oder -Setter, ein Event-Adder oder -Remover.

Empfehlungen: Typen mit NbMethods > 20 können schwer zu verstehen und zu warten sein, aber es kann Fälle geben, in denen ein hoher Wert für NbMethods sinnvoll ist.

NbFields

Definiert für Anwendung, Projekte, Namespaces, Typen. Die Anzahl der Felder.

Empfehlungen: Typen mit NbFields über 20 können schwer zu verstehen und zu warten sein, aber es kann Fälle geben, in denen ein hoher Wert für NbFields sinnvoll ist.

Metriken zu Projekten

Durch Messung der Kopplung zwischen den Typen Ihrer Anwendung bewertet CppDepend die Stabilität jedes Projekts. Ein Projekt gilt als stabil, wenn seine Typen von vielen Typen anderer Projekte verwendet werden (d. h. stabil = schmerzhaft zu ändern). Enthält ein Projekt viele abstrakte und wenige konkrete Typen, gilt es als abstrakt. So hilft Ihnen CppDepend zu erkennen, welche Projekte potenziell schwer zu warten sind (d. h. konkret und stabil) und welche Projekte potenziell nutzlos sind (d. h. abstrakt und instabil).

Hinweis: Diese Theorie und Metriken wurden zuerst durch das exzellente Buch Agile Software Development: Principles, Patterns, and Practices in C# Robert C. Martin (Prentice Hall PTR, 2006)

Afferente Kopplung (Ca)

Die Anzahl der Typen außerhalb dieses Projekts, die von Typen innerhalb dieses Projekts abhängen. Eine hohe afferente Kopplung zeigt an, dass die betreffenden Projekte viele Verantwortlichkeiten haben.

Efferente Kopplung (Ce)

Die Anzahl der Typen innerhalb dieses Projekts, die von Typen außerhalb dieses Projekts abhängen. Eine hohe efferente Kopplung zeigt an, dass das betreffende Projekt abhängig ist.

Relationale Kohäsion (H)

Durchschnittliche Anzahl interner Beziehungen pro Typ. Sei R die Anzahl der Typbeziehungen, die intern zu diesem Projekt sind (d. h. nicht zu Typen außerhalb des Projekts verbinden). Sei N die Anzahl der Typen im Projekt. H = (R + 1)/ N. Die zusätzliche 1 in der Formel verhindert H=0, wenn N=1. Die relationale Kohäsion repräsentiert die Beziehung, die dieses Projekt zu all seinen Typen hat.

Empfehlungen: Da Klassen innerhalb eines Projekts stark miteinander verbunden sein sollten, sollte die Kohäsion hoch sein. Andererseits können zu hohe Werte auf Überkopplung hinweisen. Ein guter Bereich für RelationalCohesion ist 1,5 bis 4,0.

Instabilität (I)

Das Verhältnis der efferenten Kopplung (Ce) zur Gesamtkopplung. I = Ce / (Ce + Ca). Diese Metrik ist ein Indikator für die Widerstandsfähigkeit des Pakets gegenüber Änderungen. Der Bereich für diese Metrik ist 0 bis 1, wobei I=0 ein vollständig stabiles Paket und I=1 ein vollständig instabiles Paket anzeigt.

Abstraktheit (A)

Das Verhältnis der Anzahl interner abstrakter Typen zur Anzahl der Typen. Der Bereich für diese Metrik ist 0 bis 1, wobei A=0 ein vollständig konkretes Projekt und A=1 ein vollständig abstraktes Projekt anzeigt.

Abstand zur Hauptsequenz (D)

Der senkrechte normalisierte Abstand eines Projekts von der idealisierten Linie A + I = 1 (genannt Hauptsequenz). Diese Metrik ist ein Indikator für das Gleichgewicht des Projekts zwischen Abstraktheit und Stabilität. Der Bereich ist 0 bis 1, wobei D=0 ein Projekt anzeigt, das mit der Hauptsequenz übereinstimmt, und D=1 ein Projekt, das so weit wie möglich von der Hauptsequenz entfernt ist.

Empfehlungen: Projekte mit NormDistFromMainSeq über 0.7 könnten problematisch sein.

Metriken zu Namespaces

Afferente Kopplung auf Namespace-Ebene (NamespaceCa)

Die Afferent Coupling eines bestimmten Namespace ist die Anzahl der Namespaces, die direkt von ihm abhängen.

Efferente Kopplung auf Namespace-Ebene (NamespaceCe)

Die Efferent Coupling für einen bestimmten Namespace ist die Anzahl der Namespaces, von denen er direkt abhängt. Beachten Sie, dass in Framework-Projekten deklarierte Namespaces berücksichtigt werden.

Stufe

Definiert für Projekte, Namespaces, Typen, Methoden. Der Level-Wert für einen Namespace ist wie folgt definiert:

  • Level = 0 : if the namespace doesn't use any other namespace.
  • Level = 1 : if the namespace only uses directly namespace defined in tierce projects.
  • Level = 1 + (Max Level over namespace it uses directly)
  • Level = N/A : if the namespace is involved in a dependency cycle or uses directly or indirectly a namespace involved in a dependency cycle.

Empfehlungen: Diese Metrik hilft, Projekte, Namespaces, Typen und Methoden objektiv als High-Level-, Mid-Level- oder Low-Level einzustufen. Diese Metrik ist auch nützlich, um Abhängigkeitszyklen in Ihrer Anwendung zu entdecken.

Metriken zu Typen

Typrang

TypeRank-Werte werden berechnet durch Anwenden von Google PageRank Algorithmus auf den Graphen der Typabhängigkeiten. Eine Homothetie mit Zentrum 0,15 wird angewendet, sodass der Durchschnitt von TypeRank 1 beträgt.

Empfehlungen: Typen mit hohem TypeRank sollten sorgfältiger getestet werden, da Bugs in solchen Typen wahrscheinlich katastrophaler sind.

Afferente Kopplung auf Typebene (TypeCa)

Die Afferent Coupling eines bestimmten Typs ist die Anzahl der Typen, die direkt von ihm abhängen.

Efferente Kopplung auf Typebene (TypeCe)

Die Efferent Coupling für einen bestimmten Typ ist die Anzahl der Typen, von denen er direkt abhängt. Beachten Sie, dass in Framework-Projekten deklarierte Typen berücksichtigt werden.

Empfehlungen: Typen mit TypeCe > 50 sind Typen, die von zu vielen anderen Typen abhängen. Sie sind komplex und haben mehr als eine Verantwortlichkeit. Sie sind gute Kandidaten für Refactoring.

Mangelnde Kohäsion der Methoden (LCOM)

Das Single-Responsibility-Prinzip besagt, dass eine Klasse nicht mehr als einen Grund zur Änderung haben sollte. Eine solche Klasse gilt als kohäsiv. Ein hoher LCOM-Wert deutet im Allgemeinen auf eine schlecht kohäsive Klasse hin. Der LCOM nimmt Werte im Bereich [0-1] an. Der LCOM HS (HS steht für Henderson-Sellers) nimmt Werte im Bereich [0-2] an. Ein LCOM-HS-Wert über 1 sollte als alarmierend betrachtet werden.

Von CppDepend verwendete Algorithmen:

  • LCOM = 1 – (sum(MF)/M*F)
  • LCOM HS = (M – sum(MF)/F)(M-1)
  • Wobei: M die Anzahl der Methoden in der Klasse ist, F die Anzahl der Instanzfelder in der Klasse ist, MF die Anzahl der Methoden der Klasse ist, die auf ein bestimmtes Instanzfeld zugreifen.

Empfehlungen: Typen mit LCOM > 0.8 und NbFields > 10 und NbMethods > 10 könnten problematisch sein. Typen mit LCOMHS > 1.0 und NbFields > 10 und NbMethods > 10 sollten vermieden werden.

Zyklomatische Komplexität (CC)

Definiert für Typen und Methoden. Die zyklomatische Komplexität ist eine beliebte prozedurale Softwaremetrik, die der Anzahl der Entscheidungen entspricht, die in einer Prozedur getroffen werden können. Konkret ist in C++ die CC einer Methode 1 + {die Anzahl der folgenden Ausdrücke im Rumpf der Methode}:

Gezählt: if | while | for | case | default | continue | goto | && | || | catch | ternary operator ?: | ??

Nicht gezählt: else | do | switch | try | using | throw | finally | return | object creation | method call | field access

Empfehlungen: Methoden mit CC über 15 sind schwer zu verstehen und zu warten. Methoden mit CC über 30 sind extrem komplex und sollten in kleinere Methoden aufgeteilt werden (außer sie werden automatisch von einem Tool generiert).

Instanzgröße

Definiert für Instanzfelder und Typen. Die Größe der Instanzen eines Instanzfelds ist definiert als die Größe der Instanzen seines Typs in Bytes. Die Größe der Instanz eines statischen Felds ist gleich 0.

Die Größe von Instanzen einer Klasse oder Struktur ist definiert als die Summe der Größe der Instanzen ihrer Felder plus der Größe der Instanzen ihrer Basisklasse.

Empfehlungen: Typen mit SizeOfInst über 64 können die Performance beeinträchtigen und schwer zu warten sein.

Association Between Class (ABC)

Die Metrik Association Between Classes für eine bestimmte Klasse oder Struktur ist die Anzahl der Member anderer Typen, die sie direkt im Rumpf ihrer Methoden verwendet.

Anzahl der Kinder (NOC)

Die Anzahl der Kinder einer Klasse ist die Anzahl der Unterklassen (unabhängig von ihrer Position im Unterzweig des Vererbungsbaums). Die Anzahl der Kinder einer Schnittstelle ist die Anzahl der Typen, die sie implementieren. In beiden Fällen zählt die Berechnung dieser Metrik nur Typen, die im Anwendungscode deklariert sind.

Tiefe des Vererbungsbaums (DIT)

Die Depth of Inheritance Tree einer Klasse oder Struktur ist ihre Anzahl an Basisklassen (einschließlich der Klasse System.Object, also DIT >= 1).

Empfehlungen: Typen mit DepthOfInheritance über 6 sind möglicherweise schwer zu warten.

Metriken zu Methoden

Methodenrang

MethodRank-Werte werden berechnet durch Anwenden von Google PageRank Algorithmus auf den Graphen der Methodenabhängigkeiten. Eine Homothetie mit Zentrum 0,15 wird angewendet, sodass der Durchschnitt von MethodRank 1 beträgt.

Empfehlungen: Methoden mit hohem MethodRank sollten sorgfältiger getestet werden, da Bugs in solchen Methoden wahrscheinlich katastrophaler sind.

Afferente Kopplung auf Methodenebene (MethodCa)

Die Afferent Coupling einer bestimmten Methode ist die Anzahl der Methoden, die direkt von ihr abhängen.

Efferente Kopplung auf Methodenebene (MethodCe)

Die Efferent Coupling für eine bestimmte Methode ist die Anzahl der Methoden, von denen sie direkt abhängt. Beachten Sie, dass in Framework-Projekten deklarierte Methoden berücksichtigt werden.

NbParameters

Die Anzahl der Parameter einer Methode. Ref und Out werden ebenfalls gezählt. Die this-Referenz, die in IL an Instanzmethoden übergeben wird, wird nicht als Parameter gezählt.

Empfehlungen: Methoden mit NbParameters über 5 können mühsam aufzurufen sein und die Performance beeinträchtigen.

NbVariables

Die Anzahl der im Rumpf einer Methode deklarierten Variablen.

Empfehlungen: Methoden mit NbVariables über 8 sind schwer zu verstehen und zu warten. Methoden mit NbVariables über 15 sind extrem komplex und sollten in kleinere Methoden aufgeteilt werden.

NbOverloads

Die Anzahl der Überladungen einer Methode. Wenn eine Methode nicht überladen ist, ist ihr NbOverloads-Wert gleich 1. Diese Metrik gilt auch für Konstruktoren.

Empfehlungen: Methoden mit NbOverloads über 6 können schwer zu warten sein und zu unnötig hoher Kopplung führen.

Metriken zu Feldern

Afferente Kopplung auf Feldebene (FieldCa)

Die Afferent Coupling eines bestimmten Felds ist die Anzahl der Methoden, die es direkt verwenden.

Halstead-Metriken

CppDepend berechnet verschiedene Halstead-Metriken, wie von Maurice H. Halstead in Elements of Software Science (1977) definiert. Halstead-Metriken basieren auf Definitionen von Operatoren und Operanden.

  • Operatoren: arithmetische ('+'), Gleichheits-/Ungleichheits- ('<'), Zuweisungs- ('+='), Shift- ('>>'), logische ('&&') und unäre ('*') Operatoren. Reservierte Wörter zur Angabe von Kontrollpunkten ('while') und Kontrollstrukturen ('else'), Typen ('double') und Speicherklassen ('extern'). Funktionsaufrufe, Array-Referenzen usw.
  • Operanden: Bezeichner, Literale, Labels und Funktionsnamen. Jedes Literal wird als eigener Operand behandelt.
Gesamtoperatoren (N1)

Definiert für Typen und Methoden. Die Gesamtzahl der vorhandenen Operatoren.

Gesamtoperanden (N2)

Definiert für Typen und Methoden. Die Gesamtzahl der vorhandenen Operanden.

Unterschiedliche Operatoren (n1)

Definiert für Typen und Methoden. Die Anzahl der vorhandenen unterschiedlichen Operatoren.

Unterschiedliche Operanden (n2)

Definiert für Typen und Methoden. Die Anzahl der vorhandenen unterschiedlichen Operanden. Wie oben erwähnt, wird jede Konstante als unterschiedlich behandelt.

Halstead-Programmlänge (N)

N = N1 + N2

Die Halstead-Programmlänge beschreibt die Größe des abstrahierten Programms, das durch Entfernen von allem außer Operatoren und Operanden aus dem ursprünglichen Programm erhalten wird.

Halstead-Programmvolumen (V)

V = N * log2(n1 + n2)

Dies modelliert die Anzahl der Bits, die zur Speicherung des abstrahierten Programms der Länge N benötigt werden.

Halstead-Programmlevel (L)

L = (2/n1)*(n2/N2)

L beschreibt das Verhältnis zwischen dem Volumen V des aktuellen Programms und dem Volumen V* der kompaktesten Implementierung desselben Algorithmus.

Halstead-Programmschwierigkeit (D)

D = (n1/2) * (N2/n2) = 1/L

Difficulty ist der Kehrwert von Level. Difficulty steigt mit der Anzahl der eindeutigen Operatoren.

Halstead-Programmieraufwand (E)

E = D * V

Halsteads Formel für den Aufwand, der zum Erstellen (oder Verstehen) eines Programms erforderlich ist, beschreibt den Aufwand als proportional sowohl zur Schwierigkeit als auch zum Volumen.

Halstead-Programmierzeit (T)

T = E/18 Sekunden

Die Programmierzeit gilt als direkt proportional zum Programmieraufwand.

Halstead Intelligenter Inhalt (I)

I = V / D

Halstead beabsichtigte diese Metrik als sprachunabhängiges Maß für algorithmische Komplexität.

Testen Sie CppDepend noch heute

Starten Sie Ihre 14-tägige kostenlose Testversion mit vollem Zugriff auf alle Dokumentationsfunktionen. Keine Kreditkarte erforderlich.