Software Engineering 13. Automatische Code

Werbung
Software Engineering
13. Automatische Code Analyse
Franz-Josef Elmer, Universität Basel, WS 2005/06
Software Engineering: 13. Automatische Code Analyse
2
Code Analyse: Manuell versus Automatisch
–
Manuelle Code Analyse = Code Review
●
●
Unterstützung durch ein Tool (z.B. IDE) möglich.
Vorteile:
–
–
●
Nachteile:
–
–
–
Der Mensch kann Probleme besser erkennen als ein automatische Analyse.
Flexibler in der Fokusierung auf das Wesentliche.
Der Mensch übersieht leicht Probleme.
Langsam und grosser Aufwand.
Automatische Code Analyse:
●
●
●
●
Software Tools analysieren den (Quell)-Code, erzeugen Reports
und verschicken eventuell E-Mails.
Online: Interaktive z.B. intergriert in IDE
Offline: Automatisch angeworfene Analyse (z.B. jede Nacht).
Vorteile:
–
–
●
Schnell.
Die ganze Code-Basis kann analysiert werden.
Nachteile:
–
–
Universität Basel, WS 2005/06
Problemerkennung sehr schwierig.
Erkennt Probleme, die keine sind.
© Franz­Josef Elmer 2005
Software Engineering: 13. Automatische Code Analyse
3
Arten der automatischen Analyse
–
Code Metriken:
●
Berechnung von Masszahlen, die (vielleicht) etwas über die
Qualität des Codes aussagen.
–
●
Verschiedene Typen von Metriken:
–
–
–
●
Prozedurale Metriken
Objektorientierte Metriken
etc
Report:
–
–
–
IEEE 1061: A function whose inputs are software data and whose output
is a single numerical value that can be interpreted as the degree to
which software possesses a given attribute that affects its quality.
Tabelle: Jede Zeile enthält alle gemessenen Metriken für eine Einheit des
Codes.
Granularität: Einheiten sind Module, Pakete, Klassen, Methoden, Funktionen
etc.
Überprüfung des Codes (engl. auditing):
●
●
●
Aufspüren von Verstössen gegen Regeln.
Kombiniert mit Code Metriken: Masszahl über- bzw.
unterschreitet einen kritischen Wert.
Report: Liste der Verstösse.
Universität Basel, WS 2005/06
© Franz­Josef Elmer 2005
Software Engineering: 13. Automatische Code Analyse
4
Einsatz automatischer Code Analysen
–
Für die einzelnen Entwickler:
●
●
–
Für den Chefentwickler oder das Entwicklerteam:
●
●
–
Web Site mit den Reports.
Integriert in IDE: Sofortige Warnung bei Regelverstössen.
Übersicht
Schnelles Auffinden von potentiellen Problemfeldern im Code.
Für QA und Management:
●
●
Status der aktuellen Codequalität im Projekt.
– Aber: Ergebnis muss korrekt interpretiert werden.
Teil einer Analyse durch unabhängiger Gutachter.
Universität Basel, WS 2005/06
© Franz­Josef Elmer 2005
Software Engineering: 13. Automatische Code Analyse
5
Code Metriken
–
Problem: Geeigneten Algorithmus finden, der es erlaubt aus
dem (Quell-)Code eine Zahl zu berechnen, die die Qualität
des Codes misst.
–
Beispiel:
●
●
Lines of Code (LOC): Zahl der Zeilen in Quellcode minus Zahl der
Leerzeilen und Zeilen, die nur Kommentar enthalten.
Fokus: Gesamtprojekt:
–
–
●
Keine Qualitätsaussage möglich.
Schätzung bzw. Validierung des Aufwands für Coding bzw. Testing.
●
Voraussetzung: Erfahrung mit demselben Team, derselben
Entwicklungsmethodologie und derselben Technologie.
Fokus: Klasse, Methode:
–
–
Universität Basel, WS 2005/06
Hinweis auf Bad Smells „grosse Klasse“ und „lange Methode“.
Code Review
●
der längsten Klassen und Methoden oder
●
aller Klassen und Methoden für die LOC einen kritischen Wert
überschreitet.
© Franz­Josef Elmer 2005
Software Engineering: 13. Automatische Code Analyse
6
Prozedurale Metriken
–
–
LOC: Lines of Code
NCSS: Non-Commenting Source Statements:
●
●
●
Zahl der Statements die keine Kommentare sind.
Im Gegensatz zu LOC unabhängig von der Formatierung des
Quellcodes.
Beispiel:
LOC: 7, NCSS: 4
LOC: 9, NCSS: 4
/** Removes and returns the element * on the top of the stack.
* @throws IllegalStateException * if the stack is empty.
*/
public Object pop() {
if (isEmpty()) {
throw new IllegalStateException(
"Empty stack.");
}
return _stack.remove(_stack.size()­1);
}
/** Removes and returns the element * on the top of the stack.
* @throws IllegalStateException */
public Object pop() {
if (isEmpty()) {
throw new IllegalStateException(
"Empty stack.");
}
return _stack.remove(_stack.size()­1);
}
●
Refactoring: Extract Method, Extract Class
Universität Basel, WS 2005/06
© Franz­Josef Elmer 2005
Software Engineering: 13. Automatische Code Analyse
7
Cyclomatic Complexity Number
–
CCN: McCabe's Cyclomatic Complexity Number:
●
●
●
Versuch, die prozedurale Komplexität einer
Prozedur/Funktion/Methode zu messen.
CCN = Zahl der Verzweigungen in Kontrollfluss
Java: Jedes der folgenden Statements erhöht CCN um 1:
–
–
–
–
–
●
●
if
for
while
case
catch
Variante: CCN =Zahl der Verzweigungen + Zahl der Exit-Points
Java: Jedes der folgendes Statements erhöht CCN auch um 1:
–
–
Universität Basel, WS 2005/06
return (auch implizites return beim Verlassen einer void Methode)
throw
© Franz­Josef Elmer 2005
Software Engineering: 13. Automatische Code Analyse
8
Cyclomatic Complexity Number: Beispiele
–
CCN Variante in allen Beispielen
LOC: 3, NCSS: 2, CCN: 1
void printHelloWorld() {
System.out.println("hello world");
}
←1: implizites return
LOC: 15, NCSS: 19, CCN: 7
LOC: 7, NCSS: 5, CCN: 2
void printHello(String name) {
if (name == null) {
1→
System.out.println("hello");
} else {
System.out.println("hello " + name);
}
} ←2: implizites return
String[] getOperators(int[] codes) {
String[] operators = new String[codes.length];
1→ for (int i = 0; i < codes.length; i++) {
switch (codes[i]) {
case ADD: operators[i] = "add"; break;
2→
case SUB: operators[i] = "sub"; break;
3→
case MUL: operators[i] = "mul"; break;
4→
case DIV: operators[i] = "div"; break;
5→
default: throw new IllegalArgumentException(
6→
"unkown code: " + codes[i]);
}
}
7→ return operators;
}
Universität Basel, WS 2005/06
© Franz­Josef Elmer 2005
Software Engineering: 13. Automatische Code Analyse
9
Cyclomatic Complexity Number
–
Keine Aussage über Verständlichkeit des Codes
●
Zwei Beispiele beide CCN = 9
String getOperator(int code) {
switch (code) {
case ADD: return "add";
case SUB: return "sub";
case MUL: return "mul";
case DIV: return "div";
default: throw new IllegalArgumentException(
"unkown code: " + code);
}
} ●
●
Regel: Auf alle Methoden mit
CCN ≥ 10 sollte man einen
Blick darauf werfen.
Refactoring: Extract Method
Universität Basel, WS 2005/06
void execute(String text) {
if (text == null) {
throw new IllegalArgumentException(
"Missing text");
}
StringTokenizer tokenizer = new StringTokenizer(text);
while (tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken();
if (token.equals(BAQ)) {
int n = _borders.length;
for (int i = 0; i < n; i++) {
_borders[i].increment();
}
} else if (token.equals(ZOP)) {
if (_zone != null) {
_zone.reset();
} else {
_list.clear();
}
} else if (_zone.isActive()) {
_list.add(token);
}
}
} © Franz­Josef Elmer 2005
Software Engineering: 13. Automatische Code Analyse
10
Objektorientierte Metriken
–
–
–
Problem: Es ist schwierig geeignete Metriken zu den
bekannten Design Prinzipien zu finden.
Konsequenz: Es gibt eine grosse Zahl von verschiedenen
Metriken für objektorientierte Programme.
Am bekanntesten: Chidamber-Kemerer (CK) Metriken für
Klassen:
●
WMC: Weighted Methods per Class
●
LCOM: Lack of Cohesion in Methods
●
DIT: Depth of Inheritance Tree
●
NOC: Number of Children
●
CBO: Coupling between Object Classes
●
RFC: Response for a Class
Universität Basel, WS 2005/06
© Franz­Josef Elmer 2005
Software Engineering: 13. Automatische Code Analyse
11
Weighted Methods per Class (WMC)
–
–
Definition: Die Summe der CCN aller Methoden (inkl.
Konstruktoren) oder Zahl der Methoden.
Interpretation:
●
●
Grosse WMC lassen auf applikationsspezifische Klasse mit
geringen Wiederverwendungspotential schliessen.
Je grösser WMC einer Klasse desto grösser die Abhängigkeit
ihrer Unterklassen von ihr.
Universität Basel, WS 2005/06
© Franz­Josef Elmer 2005
Software Engineering: 13. Automatische Code Analyse
12
Lack of Cohesion in Methods (LCOM)
–
Definition: LCOM = max(0, P-Q) mit P ist die Zahl der
Methodenpaare, die auf kein gemeinsames Attribute
zugreifen, und Q die Zahl der Paare, die auf mindestens ein
gemeinsames Attribute zugreifen.
–
Beispiel:
class ABC {
int a;
int b;
int c;
int sum() {
return a + b;
}
int diff() {
return a ­ b;
}
int square() {
return c * c;
}
} Universität Basel, WS 2005/06
Paare
sum:diff
sum:square
diff:square
Gemeinsame Attribute
a, b
keine
keine
P = 2, Q = 1 ⇒ LCOM = 1
© Franz­Josef Elmer 2005
Software Engineering: 13. Automatische Code Analyse
13
LCOM: Kritik
–
Lack of Cohesion möglich trotz LCOM = 0.
–
Beispiel:
class AB {
int a;
int b;
int a() {
return a;
}
int b() {
return b;
}
int bb() {
return b * b;
}
int bbb() {
return b * b * b;
}
} Universität Basel, WS 2005/06
Paare
a:b
a:bb
a:bbb
b:bb
b:bbb
bb:bbb
Gemeinsame Attribute
keine
keine
keine
b
b
b
P = 3, Q = 3 ⇒ LCOM = 0
© Franz­Josef Elmer 2005
Software Engineering: 13. Automatische Code Analyse
14
LCOM: Definition nach Li und Henry
–
–
LCOM = Zahl von disjunkten Mengen von Methoden, die wie
folgt definiert sind: Je zwei Methoden einer solchen Menge
greifen auf gemeinsames Attribute zu.
Beispiel:
class AB {
int a;
int b;
int a() {
return a;
}
int b() {
return b;
}
int bb() {
return b * b;
}
int bbb() {
return b * b * b;
}
} Universität Basel, WS 2005/06
M1 = {a}, M2 = {b, bb, bb} ⇒ LCOM = 2
© Franz­Josef Elmer 2005
Software Engineering: 13. Automatische Code Analyse
15
LCOM: Kritik
–
LCOM > 0 trotzdem kein Lack of Cohesion:
●
●
Idirekter Attributenzugriff durch Aufruf von Methoden derselben
Klasse.
Beispiel: class AB {
int a;
int b;
int a() {
return a;
}
int b() {
return b * a();
}
} –
Koppelt b() an a()
LCOM ≫ 1 trotzdem kein Problem: Data Transfer Objects
enthalten typischerweise nur Setters und Getters.
●
n Attribute: LCOM (nach CK): n⋅(2n-3), für n > 1
LCOM (nach Li & Henry): n
Universität Basel, WS 2005/06
© Franz­Josef Elmer 2005
Software Engineering: 13. Automatische Code Analyse
16
Depth of Inheritance Tree (DIT)
–
–
Definition: Maximale Länge des Vererbungspfads einer
Klasse.
Beispiele:
DIT:2
–
Object
DIT:0
Number
DIT:1
Integer
Float
A
DIT:1
DIT:2
DIT:2
DIT:0
B
C
DIT:0
D
Interpretation: Je kleiner DIT desto besser (Prinzip
Komposition vor Vererbung).
Universität Basel, WS 2005/06
© Franz­Josef Elmer 2005
Software Engineering: 13. Automatische Code Analyse
17
Number Of Children (NOC)
–
–
Definition: Zahl der direkten Unterklassen.
Beispiel:
DIT:0
A
DIT:1
NOC:0
B
NOC:2
C
DIT:1
NOC:1
DIT:2
NOC:2
D
DIT:3
NOC:0
–
E
F
DIT:3
NOC:0
Interpretation: Je grösser NOC desto wichtiger ist die Klasse
und desto mehr sollte man darauf achten, dass das
Liskovsche Substitutionsprinzip eingehalten wird.
Universität Basel, WS 2005/06
© Franz­Josef Elmer 2005
Software Engineering: 13. Automatische Code Analyse
18
Coupling between Object Classes (CBO)
–
Definition: Zahl der Klassen von denen die Klasse direkt
abhängt. Mögliche Abhängigkeiten sind:
●
●
●
–
Vererbung und Interface Implementation
Typen der Attribute, Parameter, lokalen Variablen, und
Rückgabewerte.
Klassen, deren Konstruktoren/Methoden/Attribute benutzt
werden.
Beispiel:
3: Dummy
4: Integer
–
CBO: 6
1: SampleClass
2: MyInterface
class MyClass extends SampleClass implements MyInterface {
Dummy dummy;
5: Number
Integer getNumberOfCharacters(Number number) {
return new Integer(number.toString().length());
}
6:String
} Interpretation: Je grösser CBO desto wahrscheinlicher wird
das Prinzip der schwachen Kopplung verletzt.
●
Erlaubte Ausnahme: Alle Klassen gehören zum selben
Modul/Paket (Prinzip der maximalen Kohäsion)
Universität Basel, WS 2005/06
© Franz­Josef Elmer 2005
Software Engineering: 13. Automatische Code Analyse
19
Response for a Class (RFC)
–
Definition: Anzahl Klassenmethoden + Zahl der verschiedenen direkt aufgerufenen Methoden in anderen Klassen.
–
Beispiel:
RFC: 10
public class Stack {
1
private final List _stack = new ArrayList();
2: default constructor
public void push(Object element) { 3
_stack.add(element);
4
}
public boolean isEmpty() { 5
return _stack.isEmpty();
}
6
public Object pop() { 7
if (isEmpty()) {
throw new IllegalStateException("Empty stack.");
}
8
return _stack.remove(_stack.size() ­ 1);
}
9
10
}
–
Interpretation: Analog zu CBO: Je grösser desto wahrscheinlicher die Verletzung des Prinzips der schwachen Kopplung.
Universität Basel, WS 2005/06
© Franz­Josef Elmer 2005
Software Engineering: 13. Automatische Code Analyse
20
Open Source Tools für Code Metriken
–
CCCC:
●
●
●
–
JavaNCSS:
●
●
●
–
Tool in C geschrieben analysiert C, C++, Java Quellcode. Reports
in XML und HTML
Metriken: LOC, CCN, WMC, DIT, NOC, CBO und andere
http://cccc.sourceforge.net
Tool in Java geschrieben analysiert Java Quellcode. Reports als
Text, XML oder HTML.
Metriken: NCSS, CCN, WMC und andere
http://www.kclee.de/clemens/java/javancss/
ckjm:
●
●
●
Tool in Java geschrieben analysiert Java Quellcode. Reports als
Text.
Metriken: WMC, LCOM, DIT, NOC, CBO, RFC und andere
http://www.spinellis.gr/sw/ckjm/
Universität Basel, WS 2005/06
© Franz­Josef Elmer 2005
Software Engineering: 13. Automatische Code Analyse
21
Classycle
–
Open Source Tool Suite zur Analyse der Abhängigkeiten
zwischen Java Klassen und Paketen:
●
●
–
In Java geschrieben analysiert kompilierte Java Klassen.
http://classycle.sourceforge.net
Analyser:
●
●
●
Analyse der Klassen/Paket Abhängigkeiten.
Reports in XML und HTML.
Reports enthalten (unter anderem):
–
–
–
Tabelle aller Klassen/Pakete:
●
Grösse
●
Zahl der Klassen/Pakete die dieses benutzen
●
Zahl der Klassen/Pakete die von diesem benutzt werden (=CBO)
Tabelle aller Zyklen (strong components)
DependencyChecker:
●
●
●
Findet unerwünschte direkte und indirekte Abhängigkeiten
zwischen Klassen.
Überprüft Schichtarchitektur.
Regelbasiert
Universität Basel, WS 2005/06
© Franz­Josef Elmer 2005
Software Engineering: 13. Automatische Code Analyse
22
Classycle: Gerichteter Abhängigkeitsgraph
–
Classycle ermittelt die Anhängigkeiten durch die Analyse
des sogenannten Constant Pools der .class Dateien.
–
Classycle baut einen gerichteten Graphen (engl. digraph):
●
Knoten: Klassen/Pakete
●
Kanten: Klasse/Paket X hängt von Y ab: X→Y
B
interne Klasse
A
externe Klasse
D
C
E
Universität Basel, WS 2005/06
F
G
© Franz­Josef Elmer 2005
Software Engineering: 13. Automatische Code Analyse
23
Classycle: Zyklen = strong components
–
Definition:
●
●
–
Strongly connected: Von jedem Knoten in der strong
component gibt es einen Pfad zu jedem anderen Knoten der
strong component.
Vollständigkeit: Das Hinzufügen einer oder mehrerer Konten
zerstört obige Eigenschaft.
Ein gerichtete Graph kann zu einem azyklischen gerichteten
Graphen seiner strong components kondensiert werden
c
a
b
Layer
d
3
A
B
C
D
E
F
G
Kondensation
H
d
Universität Basel, WS 2005/06
I
strong component
a
2
b
1
c
0
© Franz­Josef Elmer 2005
Software Engineering: 13. Automatische Code Analyse
24
Classycle: Eigenschaften von Zyklen
–
Classycle ermittelt für jede strong component:
●
●
●
●
●
●
–
Exzentrizität:
●
●
–
Zahl der Knoten.
Beste Fragmentgrösse: Minimum der maximalen Fragmentgrösse
Radius: Minimum der Exzentrizität
Durchmesser: Maximum der Exzentrizität
Girth: Länge des kürzesten Zyklus
Layer Index
Eigenschaft eines Knoten in einem gerichteten Graphen.
Definition:
– Finde die kürzesten Pfade zu jedem anderen Knoten.
– Exzentrizität = Maximum der Länge aller kürzesten Pfade
Beispiel:
A
B
C
Universität Basel, WS 2005/06
Von
A
A
B
B
C
C
Nach Kürzester Pfad
B
1
2
C
1
A
C
1
A
1
B
2
Knoten Exzentrizität
A
2
B
1
C
2
© Franz­Josef Elmer 2005
Software Engineering: 13. Automatische Code Analyse
25
Classycle: Maximale Fragmentgrösse
–
Maximale Fragmentgrösse ist die Eigenschaft eines Knotens
einer strong component:
●
Definition:
–
–
–
–
Entferne den Knoten
Mache eine strong component Analyse des Rest
Maximale Fragmentgrösse ist das Maximum über Zahl der Knoten der
strong components (Fragmente) aus dieser Analyse.
Beispiel:
5
A
5
2
B
2
C
E
D
4
F
5
beste Fragmentierer
Universität Basel, WS 2005/06
© Franz­Josef Elmer 2005
Software Engineering: 13. Automatische Code Analyse
26
Classycle: Refactoring von Zyklen
–
Klassenzyklen: Kriterium: Zyklus > 10
●
Häufigstes Refactoring: Extract Interface
implementiert
Interface
A
⇒
Typen Referenzen
–
I
A
Interface
Paketzyklen: Kriterium: Keine Paketzyklen zulassen.
●
Mögliche Refactorings:
–
–
–
●
Verschieben von Klassen in andere Pakete
Einführung eines neuen Pakets
Zusammenlegung eines Pakets
Bei paketübergreifendem Klassenzyklus: Eventuell erst
Klassenzyklus zerlegen.
Universität Basel, WS 2005/06
© Franz­Josef Elmer 2005
Software Engineering: 13. Automatische Code Analyse
27
Classycle: Dependency Checker
–
Überprüfung ob definierte Subgraphen voneinander direkt
oder indirekt unabhängig sind.
[set1]
direkte Abhängigkeit
[set2]
indirekte Abhängigkeit
–
Regeln (festgelegt in dependency definition files):
check [set1] directlyIndependentOf [set2]
check [set1] independetOf [set2]
Universität Basel, WS 2005/06
© Franz­Josef Elmer 2005
Software Engineering: 13. Automatische Code Analyse
28
Classycle: Dependency Checker
–
Überprüfung von Schichtarchitekturen:
Layer C
–
erlaubte direkte
Abhängigkeit
[set5]
Layer B
[set3]
[set4]
Layer A
[set1]
[set2]
verbotene direkte
Abhängigkeit bei
strikter
Schichtung
Regeln:
layer A = [set1] [set2]
layer B = [set3] [set4]
layer C = [set4]
check layeringOf A B C
check strictLayeringOf A B C
Universität Basel, WS 2005/06
© Franz­Josef Elmer 2005
Software Engineering: 13. Automatische Code Analyse
29
Open Source Auditing Tools für Java
FindBugs
http://findbugs.sourceforge.net
PMD mit CPD (Copy-Paste Detector)
http://pmd.sourceforge.net
Universität Basel, WS 2005/06
© Franz­Josef Elmer 2005
Herunterladen