Jan Schumann, G+J Manuel Pichler, Trainer & Consultant - Qafoo Statische Codeanalyse wirklich effektiv nutzen
Über uns Jan Schumann Jahrgang 1976 System- / Softwarearchitekt Entwickler von: PHP_Depend, ImageTransform Manuel Pichler Jahrgang 1978 Softwarearchitekt, Trainer & Consultant - Qafoo Entwickler von: PHP_Depend, phpundercontrol, PHPMD 2
Buchempfehlung 3
Was bedeutet Qualität? You cannot control what you cannot measure. Tom DeMarco 4
Festlegen von Qualitätskriterien Qualität ist immer relativ, ausgehend vom Betrachter Nutzer haben ihre eigene Ansprüche Kunden und Betreiber wieder Andere Und Entwickler sowieso... 5
Mögliche Qualitätskriterien Funktionalität (Benutzer) Verlässlichkeit (Benutzer, Betreiber) Benutzbarkeit (Benutzer) Effektivität (Betreiber) Wartbarkeit (Kunde, Entwickler) Portabilität (Betreiber) 6
Widerspruch nicht ausgeschlossen Porsche vs. Golf Beide erfüllen die Qualitätsansprüche an ein Auto Befördert von Ort A nach B Zuverlässigkeit Wartbarkeit Aber mit ganz unterschiedliche Komfortkriterien Performance 7 Benutzbarkeit
Konsequenz Es gibt keine beste Qualität, sondern nur die passende Qualität Durch Auswahl / Kombination geeigneter Qualitätskriterien wird eine statische Analyse erst möglich 8
Beispiel Wartbarkeit ISO/IEC 9126 definiert Wartbarkeit durch: Widerverwendbarkeit Erlernbarkeit Analysierbarkeit Anpassbarkeit Stabilität Testbarkeit 9
Warum ist Software nicht wartbar? Aufgrund zu hoher Komplexität Durch falsch genutzte Vererbung Wegen Missachtung grundlegender Architekturprinzipien Verletzung des Single-Responsibility-Prinzips Unzureichendes Information-Hiding Liskovsches Substitutionsprinzip 10
Symptome Bezogen auf einzelne Klassen Hohe Komplexität Zugriff auf externe Daten Geringer Zusammenhalt Bezogen auf Klassenhierarchien Geringe Wiederverwendung geerbter Methoden Geringe Spezialisierung Starke Erweiterung der Schnittstelle 11
Blick auf das Ganze Einzelne Metriken Sind ein guter Indikator Codezeilen, Komplexität, Kombination von Metriken Geben wesentlich tiefere Einblicke Erkennung von Code-Smells Schwellenwerte Werden zur Einordnung benötigt 12
Design Disharmonies / Code Smells 13 Identity Klasse übernimmt mehrere Aufgaben Unausgewogenes Verhältnis zwischen Daten und Operationen Classification Vererbung dient primär der Wiederverwendung Die Schnittstelle der Basisklasse wird zu stark erweitert Die Austauschbarkeit von Implementierung ist nicht gewährleistet
Identity - Design Disharmony WMC Weighted Method per Class 14
Identity - Design Disharmony WMC Weighted Method per Class LOC Lines Of Code 15
Identity - Design Disharmony WMC Weighted Method per Class LOC TCC Lines Of Code Tight Class Cohesion 16
Identity - Design Disharmony WMC Weighted Method per Class LOC TCC Lines Of Code Tight Class Cohesion 17
Identity Ausprägungen God Class / Large Class Erfüllt eine Vielzahl von Aufgaben im System und verwendet meist Daten anderer Klassen Feature Envy Implementiert Verhalten, das zumeist auf den Daten anderer Klassen operiert Data Class Implementiert selbst kein Verhalten, stellt aber seine Daten direkt oder indirekt bereit 18
Identity Refactorings God Class Extract Class (149), Extract Subclass (330) Extract Interface (341) Feature Envy Extract Method (110), Move Method (142) Move Field (146) Data Class 19 Extract Method (110), Move Method (142) Hide Method (303)
Identity Beispiel Feature Envy class Calculator { Data Class class Operands { protected $o = null; //... public function divide() { $r = $this->o->getright(); $l = $this->o->getleft(); if ($r === 0) { return 0; return $l / $r; protected $left = 0; protected $right = 0; //... public function getleft() { return $this->left; public function getright() { return $this->right; 20
Identity Beispiel Move Field (146) Move Method (142) class Calculator { class Operands { protected $left = 0; protected $right = 0; protected $left = 0; protected $right = 0; //... //... public function divide() { if ($this->right === 0) { return 0; return $this->left / $this->right; public function divide() { if ($this->right === 0) { return 0; return $this->left / $this->right; 21
Classification Design Disharmony NAS Newly Added Services 22
Classification Design Disharmony NAS Newly Added Services PNAS Percentage NAS 23
Classification Design Disharmony NAS Newly Added Services PNAS Percentage NAS BOvR Base Overriding Ratio 24
Classification Design Disharmony NAS Newly Added Services PNAS Percentage NAS BOvR Base Overriding Ratio BUR Base Class Usage Ratio 25
Classification Design Disharmony NAS Newly Added Services PNAS Percentage NAS BOvR Base Overriding Ratio BUR AMC Base Class Usage Ratio Added Method Complexity 26
Classification Design Disharmony NAS Newly Added Services PNAS Percentage NAS BOvR Base Overriding Ratio BUR AMC Base Class Usage Ratio Added Method Complexity 27
Classification - Ausprägungen Refused Parent Bequest Ignoriert die Elternklasse, implementiert viele Dienste neu (Code-Duplizierung) Die Elternklasse bietet Dienste, die nur eine Untermengen der abgeleiteten Klassen nutzt Tradition Breaker Ignoriert die Schnittstelle der Elternklasse Führt eine Vielzahl neuer Dienste ein, die eine Substitution unterbinden 28
Classification - Refactorings Refused Parent Bequest Replace Inheritance with Delegation (352) Push Down Method (328) Push Down Field (329) Tradition Breaker Hide Method (303) Pull Up Method (322) Extract Class (149), Extract Subclass (330) 29
Classification - Beispiel Refused Parent Bequest abstract class List { public abstract function getall(); protected function filter($objects) { /* */ class DocumentList extends List { public function getall() { return $this->filter($this->docs); class ImageList extends List { public function getall() { return $this->filter($this->images); class CommentList extends List { public function getall() { return $this->comments; 30
Classification - Beispiel Replace Inheritance with Delegation (352) abstract class List { protected $helper = null; public abstract function getall(); class DocumentList extends List { public function getall() { return $this->helper->filter($th..); class ImageList extends List { public function getall() { return $this->helper->filter($th..); class CommentList extends List { /* */ class FilterHelper implements Filter { public function filter(list $this) { /* */ 31
Schwellenwerte Ein interessanter, aber auch umstrittener Aspekt beim Einsatz von Softwaremetriken sind die verwendeten Schwellenwerte Denn sie.. liegen immer im Ermessen des Betrachters haben großen Einfluss auf das Endergebnis Ein guter Ausgangspunkt für die Bestimmung von Schwellenwerten sind gemessene Mittelwerte eigener Projekte von Open-Source-Projekten 32
Danke However, a metric is not a god, it is merely a measurement against an arbitrary standard Robert C. Martin 33
Verwendete Softwaremetriken CYCLO: Zyklomatische Komplexität [1-n] WMC: Weighted Method per Class [0-n] TCC: Tight Class Cohesion [0-1] LOC: Lines Of Code [1-n] BUR: Base Class Usage Ratio [0-1] BOvR: Base Class Overriding Ration [0-1] NAS: Newly Added Service [0-n] PNAS: Percentage of NAS [0-1] 34