Module (Funktionen und Methoden)


Metriken

Zyklomatische Kompletität v(G)
Zyklomatische Zahl des Kontrollflußgraphen G plus 1, bzw. Anzahl der Basispfade (minimale Anzahl von Pfaden, die linear kombiniert jeden Pfad durch den Graphen erzeugen können).
v(G) = e - n + 2 oder
v(G) = Anzahl der Bedingungen + 1
Essentielle Komplexität ev(G)
Zyklomatische Kompletität des reduzierten Kontrollflußgraphen G', der erzeugt wird in dem der Graph G solange um alle Elemente strukturierter Programmierung reduziert wurde bis er keine mehr enthält.
ev(G) soll also angeben in welchem Maße der Code unstrukturiert ist; und somit schwer nachvollziehbar und schlecht zu warten und zu testen ist.
Normalisierte Zyklomatische Komplexität nv(G)
Quotient aus Zyklomatischer Komplexität und Anzahl der Zeilen:
nv(G) = v(G) / nl
"Komplexitäts-Dichte"
Modul Design Komplexität iv(G)
Zyklomatische Komplexität des reduzierten Graphen G', der erzeugt wird in dem die Kontrollstrukturen entfernt werden, in denen keine anderen Module aufgerufen werden.
Global Data Complexity
Zyklomatische Komplexiität des reduzierten Graphen G', der erzeugt wird in dem alle Entscheidungen und Schleifen entfernt werden, die keinen Zugriff auf Globale Variable oder Parameter enthalten.
Dabei wird nicht nach lesenden und schreibenden Zugriffen unterschieden.
Zugriffe auf globale Konstanten werden wie solche auf globale Variablen behandelt

Messergebnisse (tabellarisch)

Umfang (LOC)

Komplexität


Messergebnisse (graphische Zusammenfassung und Auswertung)

Kummulatives Histogramm der wichtigsten Komplexitäts-Metriken

click to enlarge

speziell abgetragen sind jeweils die Werte an den Schwellwerten

betrachtet man jedes Komplexitätsmass einzeln gilt: zwischen 7 und 9 Prozent (65-85) der Module überschreiten in den entsprechenden Metriken die festgelegten Schwellwerte


Scatterplot


(Zusammenhang zwischen v(G) und ev(G), Zuverlässigkeit und Wartbarkeit)

click to enlarge

    AnzahlProzent   AnzahlProzent
unmaintainable   31 2.9%   41 3.9%
maintainable   952 89.7%   37 3.5%
 
  reliable   unreliable


Scatterplot bewertet (1)


"Verstehbarkeit" im Quadrant v(G) > 10 und ev(G) > 4 (unzuverlässig und unwartbar)

subjektive Bewertung durch "Anschauen"
schlecht:12x Bsp: TC_812ISA::ExecuteCmd(char*) v ev iv
naja: 19x Bsp: TBraun_Psd::PsdInit() v ev iv
geht: 10x Bsp: TMList::ParsingAxis(char*) v


Scatterplot bewertet (2)

Beispiele für den Quadrant v(G) > 10 und ev(G) < 4 (wartbar aber unzuverlässig)

Diese Module sind in der Mehrheit durch große Fallunterscheidungen (switch und switch-Ersatz). Häufig sind das dialog procedures oder Parsing-Methoden.

  • MenuSelect(HWND*,unsigned_int,long) v ev iv
  • DoCommandsChild(HWND*, unsigned int, long) v ev iv
  • DoCommandsFrame(HWND*, unsigned int, long) v ev iv

  • TSteering::ParsingCmdParam(char*) v ev iv

Es gibt aber auch Module die davon Abweichen.

  • TBitmapSource::DrawMeasurementArea(HDC hdc) v ev iv

Kiviat-Diagramm

 iv(G) v(G) nl nv(G) ev(G)
max4570296134
min1110,011
avg2,793,6419,920,371,70
thr710660,404

Die Mittelwerte liegen alle liegen alle gut unterhalb der Schwellwerte, nur bei edr Normaliesierten Kompelxität nv(G) liegt der Mittelwert recht dicht beim Schwellwert, was aber wohl auf eine unzutreffende Verschiebung durch einen sehr hohen Anteil von Modulen mit nv(G)=1 (20%) zurückzuführen ist, die aber tatsächlich sehr einfache Module sind (siehe unten).

Außerdem ist zu erkennen daß - vor allem bei den Komplexitätsmaßen - es Module gibt die die Schwellwerte um mehr als das 5- bis 7-fache übersteigen. Da es sich aber um Maximalwerte handelt ist dies zur Beurteilung nur bedingt geeignet, da jeweils ein einziger Ausreißer genügt um das entsprechende Bild zu erzeigen. Trotzdem ist das Vorkommen solcher Extremwerte sicher bedenklich.


sonstiges

Zusammenhang zwischen Zyklomatischer bzw. Essetieller Komplexität und Größe (Anzahl der Zeilen)

click to enlarge

hier ist eine relativ gute Korrelation zu erkennen; wenn man für die zyklomatische Komplexität einen Schwellwert von 10 festlegt, kann man für die Größe von Modulen eine Obergrenze von 60 Zeilen als Richtlinie ableiten

click to enlarge

hier liegt eine wesentlich schlechtere Korrelation vor, was aber plausibel ist da zur Bestimmung der Essentiellen Komplexität eine Reduktion der Graphen vorgenommen wird und dadurch der Zusammenhang zur Größe aufgelöst wird. (Ideal wäre nach Definition für jedes Modul unabhängig von der Größe der Wert 1)

Histogramm für die Normalisierte Komplexität

der überdimensional große Balken bei 1, der 20% aller Module repräsentiert, umfasst hauptsächlich Get-/Set-Methoden bzw. die Standartimplemetationen die in den RTK-Quellen häufig für virtuelle Methoden implementiert werden, z.B.:

    virtual void SetSpezificParametersDlg(void) {};
    virtual int  SingleStepMeasurement(int) {return 0;};
    virtual int  GetData(WORD*,WORD,WORD) {return 0;};