Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

1 WS 2012 Software-Engineering II Refactoring.

Ähnliche Präsentationen


Präsentation zum Thema: "1 WS 2012 Software-Engineering II Refactoring."—  Präsentation transkript:

1 1 TIT10AIK @ WS 2012 Software-Engineering II Refactoring

2 2 TIT10AIK @ WS 2012 Themenübersicht »Objektorientierung »Aspektorientierung »Vorgehensmodelle »UML »Analyse- & Entwurfsmuster »Objektorientiertes Testen »Versionsverwaltung »Refactoring »Labor (Praktischer Teil)

3 3 TIT10AIK @ WS 2012 Refactoring Refactoring, Improving The Design Of Existing Code Martin Fowler ISBN: 0-201-48567-2 412 Seiten (Englisch) ISBN: 3-827-32278-2 (Deutsch)

4 4 TIT10AIK @ WS 2012 Code Quality Code Quality Management Frank Simon, Olaf Seng, Thomas Mohaupt 340 Seiten ISBN: 3-898-64388-3 (Deutsch)

5 5 TIT10AIK @ WS 2012 Refactoring Refactoring is the process of changing a software system in such way that it does not alter the external behaviour of the code yet improves its internal structure M. Fowler, Refactoring

6 6 TIT10AIK @ WS 2012 Grundsätze »Bestehender Quellcode wird verbessert »Die Funktionalität des Quellcodes wird nicht verändert »Refactoring entspricht dem Aufräumen von Quellcode »Bietet standardisierte Lösungen für Standard-Probleme

7 7 TIT10AIK @ WS 2012 Weshalb sollte man das tun? Geläufige Argumente gegen Refactoring: 1.Der Code funktioniert doch. Weshalb sollte man ihn ändern? 2.Never touch a running system 3.In dieser Zeit könnte man Sinnvolles entwickeln

8 8 TIT10AIK @ WS 2012 1) Der Code funktioniert doch! »Viele Software-Projekte werden zu Beginn mit einem großen Aufwand in Planung und Design programmiert Gut entworfenes Software-System Funktion 1a Funktion 2 Funktion 1b Funktion 3

9 9 TIT10AIK @ WS 2012 1) Der Code funktioniert doch! »Ohne Refactoring wird das Design der Software mit der Zeit schlechter »Änderungen am Quellcode tragen dazu bei, dass der Quellcode seine Struktur verliert »Vor allem wenn es um kurzzeitige Ziele geht Software-System nach einiger Zeit ohne Refactoring Funktion 1a Funktion 2 Funktion 1b Funktion 3

10 10 TIT10AIK @ WS 2012 1) Der Code funktioniert doch! »Refactoring entspricht dem Aufräumen von Quellcode Software-System nach einem Refactoring Funktion 1a Funktion 2 Funktion 1b Funktion 3

11 11 TIT10AIK @ WS 2012 1) Der Code funktioniert doch! »Je schwieriger es ist, das Konzept im Quellcode zu erkennen, desto schwieriger ist es, dieses Konzept zu verfolgen Gebräuchlicher Fehler in der SW-Entwicklung: »Redundanter Quellcode: »Bei späteren Modifikationen müssen alle Stellen angepasst werden »Je mehr Code-Zeilen, desto schwieriger wird es »Je weniger redundante Stellen, desto geringer die Wahrscheinlichkeit etwas zu vergessen

12 12 TIT10AIK @ WS 2012 2) Never touch a running system »Daraus folgt i.d.R: »Man hat nicht genügend Kenntnis bzw. Kontrolle über den Quellcode »Der Quellcode ist unflexibel geschrieben oder wird nicht komplett verstanden »Gerade in diesem Fall sollte der Quellcode angepasst werden

13 13 TIT10AIK @ WS 2012 3) In dieser Zeit könnte man Sinnvolles entwickeln »Oft Verteidigungsbedarf gegenüber den Vorgesetzten »Zeit für Refactoring ist keine verschwendete Zeit »Mit Hilfe von Refactoring kann Software schneller entwickelt werden »Verbessert Design und Lesbarkeit »Gutes Design ist entscheidend für schnelle Software-Entwicklung »Ohne gutes Design können für eine Weile gute Fortschritte gemacht werden, bald jedoch wird die Entwicklung langsamer werden »Kann Fehler verringern oder aufdecken, erhöht damit die Qualität

14 14 TIT10AIK @ WS 2012 Grundvoraussetzung »Wir wollen keine neuen Fehler einbauen! »Automatisierte Tests sind deshalb Grundvoraussetzung »Die Testabdeckung (Code- Coverage) der zu ändernden Stelle muss hervorragend sein

15 15 TIT10AIK @ WS 2012 Der richtige Zeitpunkt »Kein fester Termin »(Wie Z.B. 2x pro Woche) »Wenn beim Entwickeln der Quellcode zu schwer zu verstehen ist »Wenn das bisherige Design zu unflexibel ist »Beim Finden von Bugs »Bugs sind oft ein Zeichen, dass der Quellcode dem Entwickler nicht klar genug war »Bei Code Reviews

16 16 TIT10AIK @ WS 2012 The Two Hats, K. Beck Refactoring New Features Software-Entwickler »Der Entwickler trägt zur selben Zeit immer nur einen Hut »Beim Entwickeln neuer Features wird die Struktur des Quellcodes nicht angepasst »Beim Refactoring werden keine neuen Funktionen entwickelt »Die Hüte können beim Software-Entwickeln oft in kurzen Abständen gewechselt werden

17 17 TIT10AIK @ WS 2012 Der falsche Zeitpunkt »Wenn der Quellcode nicht funktionsfähig ist »Wenn der komplette Teil einfacher komplett neu geschrieben werden könnte »Aber: Kompromisse möglich! »Fehlerhafte Codestellen in logische Teile trennen und Segment für Segment entscheiden, ob es refactort wird

18 18 TIT10AIK @ WS 2012 Rolle des Refactoring für Code Reviews »Code Reviews: Helfen, Wissen in einem Entwicklerteam zu verbreiten »Refactoring hilft, Quellcode anderer besser zu verstehen »Normale Code Reviews: »Reviewer schaut sich den Quellcode an »Reviewer gibt Vorschläge »Code Reviews mit Refactoring: »Reviewer refactort den Quellcode »Reviewer bekommt dadurch Ideen, an die er zuvor nicht gedacht hätte »Dem Reviewer wird sofort klar, ob die Vorschläge praktikabel sind oder nicht

19 19 TIT10AIK @ WS 2012 Refactoring vs. Design? »Grundsätzlich: Nein! »Software-Design ist meist der wichtigste Teil professioneller Softwareentwicklung »Programmierer werden im Vergleich zu Software- Architekten oft als Mechaniker bezeichnet – keine intellektuelle Herausforderung »Es gibt jedoch Ansätze, bei denen zu Beginn ohne extensives Software-Design entwickelt wird »Bei eXtreme Programming wird oft zunächst ein Prototyp entworfen »Aber auch bei eXtreme Programming werden grundlegende Design-Überlegungen zuerst gemacht Ersetzt Refactoring die Planungs- und Entwurfsphase bei der Software-Entwicklung?

20 20 TIT10AIK @ WS 2012 YAGNI »You Aint gonna need it »Prinzip bei XP »Oft wird versucht, schon zu Beginn das Perfekte Design zu entwerfen »Die Architektur wird unnötig kompliziert »Komplexere/flexiblere Systeme sind schwieriger zu warten »Durch das Anwenden von Refactoring ist es legitim, weniger flexiblere Systeme zu entwerfen »Das System kann an die Gegebenheiten angepasst werden »Weniger Druck, zu Beginn die ultimative Lösung zu finden »Die Lösungen sollten einfach sein »Nach wie vor: Stellen, die sich häufig ändern, isolieren und flexibel machen

21 21 TIT10AIK @ WS 2012 Refactoring – aber was? »Große Herausforderung »Was ist guter, was ist schlechter Code? »Welche Stellen des Codes sollen refactort werden? »Martin Fowler definiert 22 Indikatoren für schlechten Quellcode: Bad Smells In Code »Die Kenntnis dieser Smells dient auch dazu, solche Fehler von vorne herein zu vermeiden

22 22 TIT10AIK @ WS 2012 #1 - Duplicate Code »Identische Codestrukturen an verschiedenen Stellen »Bester Indikator für schlechten Code public void movieEvening() { Dude x = this.findMovieFan(); Movie m1 = this.findMovie(1); Movie m2 = this.findMovie(2); x.drinkBeer(); x.watchTV( m1 ); x.drinkBeer(); x.watchTV( m2 ); } public void soccerEvening() { Dude x = this.findSoccerFan(); Movie m1 = this.get1stSoccerHalf(); Movie m2 = this.get2ndSoccerHalf(); x.drinkBeer(); x.watchTV( m1 ); x.drinkBeer(); x.watchTV( m2 ); } Harmloses Beispiel! Oft werden komplette Funktionen kopiert!

23 23 TIT10AIK @ WS 2012 #1 - Duplicate Code public void movieEvening() { Dude x = this.findMovieFan(); Movie m1 = this.findMovie(1); Movie m2 = this.findMovie(2); x.drinkBeer(); x.watchTV( m1 ); x.drinkBeer(); x.watchTV( m2 ); } public void soccerEvening() { Dude x = this.findSoc..(); Movie m1 = this.get1stSo.. Movie m2 = this.get2ndSo.. x.drinkBeer(); x.watchTV( m1 ); x.drinkBeer(); x.watchTV( m2 ); } »Wird die prinzipielle Abendbeschäftigung geändert, müssten alle Stellen angepasst werden »Je mehr Stellen es gibt, desto höher die Wahrscheinlichkeit, dass etwas vergessen wird

24 24 TIT10AIK @ WS 2012 #1 - Duplicate Code »Abhilfe im konkreten Fall: »Duplikaten Quellcode in eine separate Methode extrahieren public void movieEvening() { Dude x = this.findMovieFan(); Movie m1 = this.findMovie(1); Movie m2 = this.findMovie(2); x.drinkBeer(); x.watchTV( m1 ); x.drinkBeer(); x.watchTV( m2 ); } public void soccerEvening() { Dude x = this.findSoc..(); Movie m1 = this.get1stSo.. Movie m2 = this.get2ndSo.. x.drinkBeer(); x.watchTV( m1 ); x.drinkBeer(); x.watchTV( m2 ); } this.spendTVEvening( x, m1, m2 );

25 25 TIT10AIK @ WS 2012 #2 – Long Methods »Lange Methoden sind »Schwer zu verstehen »Schwer zu warten »Richtlinie: »Sobald Bedarf da ist, den Code mit Inline-Kommentaren (//) zu erklären »Abhilfe: »Methode aufteilen in kurze Methoden, die genau einen Zweck erfüllen

26 26 TIT10AIK @ WS 2012 #3 – Large Class »Große Klassen sind »Schwer überschaubar »Verstoßen meistens gegen das Design- Prinzip Separation of Concerns - eine Klasse soll genau einem Zweck dienen »Abhilfe »Codeblöcke in zusätzliche Klassen oder in Subklassen auslagern »Dadurch Separation of Concerns gewährleisten

27 27 TIT10AIK @ WS 2012 #4 – Long Parameter List »Methoden bekommen sehr viele Parameter übergeben »Bei objektorientierter Programmierung unüblich »Macht Methodenaufrufe komplizierter und schlecht wieder verwendbar void doSomething( int x1, int x2, int x3, int x4, … ) { // use x1.. x4 }

28 28 TIT10AIK @ WS 2012 Ausnahme: Wenn eine starke Bindung auf jeden Fall vermieden werden muss (Dependency Injection) #4 – Long Parameter List »Abhilfe: »Objekt, das aufgerufen wird, besitzt Informationen direkt oder durch Objekte class SomeClass { void setX1( int x1 ) { this.x1 = x1; } void setX1( int x2 ) { this.x2 = x1; } void doSomething() { // use this.x1.. this.x4 }

29 29 TIT10AIK @ WS 2012 #5 – Divergent Change »Bei der Änderung verschiedener Eigenschaften am System müssen viele Methoden einer Klasse angepasst werden »Abhilfe: »Stellen, die sich häufig ändern, identifizieren und in eine separate Klasse isolieren

30 30 TIT10AIK @ WS 2012 #6 – Shotgun Surgery »Ähnlich wie #5 – Divergent Change »Jedes Mal, wenn eine Änderung gemacht wird, müssten viele kleine Änderungen an vielen Dateien gemacht werden »Problematisch, da dann häufig Stellen vergessen werden »Abhilfe: »Methoden, die sich häufig ändern identifizieren und in eine separate Klasse verschieben

31 31 TIT10AIK @ WS 2012 #7 – Feature Envy »Eine Methode (im Beispiel someOperation) verwendet mehr Attribute von einer anderen Klasse als von der, in der sie sich befindet »Hinweis: »Das Prinzip der Kapselung sei hier vorausgesetzt »Ein direkter Zugriff auf als public markierte Attribute macht das Design unflexibel

32 32 TIT10AIK @ WS 2012 #7 – Feature Envy »Lösung: Methode in die beneidete Klasse verschieben Problem: Abhängigkeiten von mehreren Objekten Ansatz: Methode partitionieren oder mit Hilfe von Design Patterns neu strukturieren

33 33 TIT10AIK @ WS 2012 #8 – Data Clumps »Oft treten die gleichen Datentypen gleichzeitig auf »In Methodensignaturen »In Klassenattributen einiger Klassen class Jukebox { String currentSongName; String currentArtistName;.. int playtime; void play( String songName, String artistName ) {…} }

34 34 TIT10AIK @ WS 2012 class Song { String songName; String artistName; } class Jukebox { Song currentSong; int playtime; void play( Song song ) {…} } #8 – Data Clumps »Abhilfe: Zusammenhängende Attribute gehören in eine gemeinsame Klasse

35 35 TIT10AIK @ WS 2012 #9 – Primitive Obsession »Für die Speicherung von Daten werden primitive Datentypen extensiv verwendet public class MovieRental { int price; int currency; int ZIPCode; Date rentalStart; Date rentalEnd; } Währungen Spezial- zahlen Ranges Abhilfe: Spezielle Objekte erstellen Konkret: Class Money, Class ZIPCode, Class RentalRange M. Fowler: You can move out of the cave Into the centrally heated world Of objects [...]

36 36 TIT10AIK @ WS 2012 #10 – Switch Statements »Switch-Anweisungen sind ein Zeichen von nicht objektorientiertem Quellcode »Oft die gleichen Anweisungen für alle Bedingungen im Quellcode verteilt »Code Duplizierung »Wird Ausprägung geändert, müssen alle Switch-Statements angepasst werden »Die Lösung ist meist Polymorphismus »State Pattern »Behaviour Pattern »Template Method »Gibt es nur wenige Ausprägungen, könnte Polymorphismus ein Overkill sein

37 37 TIT10AIK @ WS 2012 #11 – Parallel Inheritance Hierarchies »Spezialfall von Shotgun Surgery »Wenn eine Subklasse von einer Klasse gemacht wird, muss auch eine Subklasse von einer anderen gemacht werden »Durch das Verschieben der gemeinsamen Eigenschaften der Klassen in eine gemeinsame Methode kann die Abhängigkeit gelöst werden

38 38 TIT10AIK @ WS 2012 #12 – Lazy Class »Klassen, die nahezu keine Funktionalität besitzen »Folge von Refactoring – Aufgaben wurden in andere Klassen verschoben »Folge von im voraus geplanten Features, die nie entwickelt oder gebraucht wurden »Diese sollten eliminiert werden »Methoden in Klassen verschieben, die ähnliches bereits erledigen

39 39 TIT10AIK @ WS 2012 #13 – Speculative Generality »Der Entwickler hat gegen das YAGNI- Prinzip verstoßen »Es werden für die Zukunft vermeintlich nützliche Sachen implementiert »Wenn benötigt, sind sie sehr hilfreich, sie waren ja auch im Gesamt-Design eingeplant »Wenn nicht benötigt sollte man sie loswerden - das System wird ansonsten komplexer und schwerer wartbar »Erkennbar daran, dass die Methoden ausschließlich von Testklassen aufgerufen werden

40 40 TIT10AIK @ WS 2012 #14 – Temporary Field »Es gibt Instanzvariablen, welche nur in bestimmten Methoden verwendet werden »Nur in einem Teil einer Klasse »Als Zwischenvariablen »Attribute, die nur in bestimmten Kontexten gültig sind, sind schwer erkennbar und können andere Entwickler verwirren »Ansatz: »Den Teil der Klasse in eine separate Klasse extrahieren »Null-Objekte einführen, die bei einem undefinierten Zustand definierte Aktionen durchführen

41 41 TIT10AIK @ WS 2012 #15 – Message Chains »Der Client holt von einem Objekt ein anderes Objekt, welches es nach einem Objekt fragt, von dem es ein Objekt … »Jede Änderung an der Beziehung zwischen den Objekten erfordert eine Änderung am Client

42 42 TIT10AIK @ WS 2012 #15 – Message Chains Schritt 1 Das erste aufgerufene Objekt bietet die Möglichkeit sofort an die gewünschten Daten zu kommen

43 43 TIT10AIK @ WS 2012 #15 – Message Chains Schritt 2 Ggf. die weiteren Klassen auch direkt mit den Daten versorgen So kann die Bekanntschafts- beziehung zwischen Client und den Klassen gering gehalten werden Ändert sich die Beziehung zw. Klasse2 und Klasse3, hat dies weder Einfluss auf den Client noch auf Klasse1

44 44 TIT10AIK @ WS 2012 #16 – Middle Man »Kapselung ist in der OOP ein wichtiger Faktor »Dadurch wird es zunächst irrelevant, ob die Daten aus der eigenen oder mithilfe einer Delegate-Klasse zurückgegeben werden »Bei Middle Man delegiert eine Klasse einen Großteil ihrer Methoden an Delegate- Klassen »Diese Umweg sollte man Entfernen »Lösung: Mittelmann entfernen und Client- Klasse direkt mit dem Delegate kommunizieren lassen

45 45 TIT10AIK @ WS 2012 #17 – Inappropriate Intimacy »Eine Klasse verwendet Attribute einer anderen Klasse sehr ausgiebig »Das führt dazu, dass die Klasse sehr anfällig für Veränderungen der anderen Klasse wird »Ansätze: »Wenn es nur einige Methoden sind, diese in die andere Klasse verschieben »Wenn ausschließlich diese Klasse auf die Attribute der anderen Klasse zugreift, das Attribut in diese Klasse verschieben »Wenn beide Klassen gemeinsame Interessen haben, diese Stellen in eine separate Klasse extrahieren

46 46 TIT10AIK @ WS 2012 #18 – Alternative Class with different Interfaces »Klassen, die dem selben Zweck dienen, sollten gleich heißen »Methoden, die eine unterschiedliche Signatur aber die selbe Funktion haben, sollten gleich heißen »Sind diese Methoden in unterschiedlichen Klassen, führe sie zusammen »Wenn es sich um zwei benachbarte Subklassen handelt, überführe die Funktionalität in die Superklasse

47 47 TIT10AIK @ WS 2012 #19 – Incomplete Library Class »Third-Party-Libraries haben oft eine zu geringe Funktionalität »Entwickler tendieren dazu, Funktionalität direkt im verwendenden Code hinzuzufügen »Benötigt man die Funktionalität erneut muss der Code kopiert werden Date contractStart = … ; … Date nextYear = new Date( contractStart.getYear() +1, contractStart.getMonth(), contractStart.getDay() );

48 48 TIT10AIK @ WS 2012 #19 – Incomplete Library Class »Ein oft gesehener Ansatz sind Helper-Klassen »Akzeptabler Ansatz class DateHelper { public static Date getNextYear( Date current ) { return new Date( current.getYear() +1, current.getMonth(), current.getDay() ); }

49 49 TIT10AIK @ WS 2012 #19 – Incomplete Library Class »Statische Helper-Klassen erlauben keine OOP Methodiken »Ableitung und Vererben der Funktionalität nicht möglich »Delegation der Funktionalität nicht möglich class DateHelper { public static Date getNextYear( Date current ) { … }

50 50 TIT10AIK @ WS 2012 #19 – Incomplete Library Class »Bester Ansatz: »Eigene Klasse schreiben »Entweder von der Library-Klasse ableiten oder eine Wrapper-Klasse für sie schreiben class MyDate extends Date { public Date nextYear() { … } } class MyDate { public MyDate( Date referral ) { … } public Date nextYear() { … } } oder

51 51 TIT10AIK @ WS 2012 #20 – Data Class »Data Classes (Beans) sind Klassen, die lediglich Daten speichern »Sie haben nur Getter und Setter haben »Prinzipiell in Ordnung class Subscription { public Date getValidUntil() { … } public void setValidUntil( Date date ) { … } }

52 52 TIT10AIK @ WS 2012 #20 – Data Class »Sie erfüllen keinen tatsächlichen Zweck »Wird häufig eine Funktionalität in Verbindung mit den gespeicherten Daten benötigt, ist es besser, Methoden in die Data Class zu integrieren class Subscription { public Date getValidUntil() { … } public void setValidUntil( Date date ) { … } public boolean isStillValid() { … } public int daysLeft() { … } }

53 53 TIT10AIK @ WS 2012 #21 – Refused Bequest »Verweigertes Vermächtnis »Eine Subklasse will viele Methoden der Superklasse nicht unterstützen »Indikator dafür, dass die Vererbungshierarchie ungünstig ist Methoden werden überschrieben

54 54 TIT10AIK @ WS 2012 #21 – Refused Bequest »Ansatz: »Versuchen, eine Geschwister-Klasse zu erzeugen, die auch von der Superklasse erbt und die unvereinbaren Fähigkeiten der Basisklasse beinhaltet Gemeinsame Implementierung oder abstrakt Jeweilige Implementierungen

55 55 TIT10AIK @ WS 2012 #22 – Comments »Inline-Kommentare(//): »Grundsätzlich natürlich gut! »Indikator für unverständlichen Quellcode »Entschuldigen komplexe Sub- Algorithmen inmitten von langen Methoden void doSomething { … // sort data with QuickSort for( int i = 0; i < … ; i++ ) { … } … }

56 56 TIT10AIK @ WS 2012 #22 – Comments »In der Regel schreien Inline-Kommentare förmlich danach, dass diese Code-Stellen in neue Methoden ausgelagert werden sollten »Auch bei einzeiligen Anweisungen kann dies Sinn machen: // Calculate next year Date y = new Date(x.getYear()+1,x.getMonth(),x.getDay()); Beispiel für Extraktion der Methode in diesem Beispiel: Siehe #19 – Incomplete Library Class

57 57 TIT10AIK @ WS 2012 Aufspüren von Referenzen »Beim Refactoring ist es essentiell zu wissen, welche Klassen bestimmte Methoden oder Attribute verwenden »Wird eine Methode umbenannt oder verschoben, müssen alle Referenzen angepasst werden »Moderne IDEs: »Unterstützen das Auffinden von Aufrufs- auf Verwendungshierarchien »CTRL-ALT-H / CTRL-H bei Eclipse »Alternative: »Methode temporär auskommentieren »Compile errors suchen »Problemfall: Methoden, die Methoden aus Superklassen überschreiben, hier wird kein Syntaxfehler auftreten! »Bei schwach typisierten Programmiersprachen: »Suchfunktion des Editors »Automatisches Search/Replace ist nicht empfehlenswert, es könnten ungewollt andere Anweisungen überschrieben werden »Vorsicht: »Wird die Reflection API verwendet, um Methoden aufzurufen, kann dies die beste IDE nicht feststellen

58 58 TIT10AIK @ WS 2012 Code-Metriken »Maß für eine bestimmte Einheit bei einer Software »Viele der Code Smells können in Metriken ausgedrückt werden »Duplicate Code »Long Method »Huge Class »Long Parameter List »Weitere Metriken definieren Eigenschaften von qualitativ hochwertigem Quellcode

59 59 TIT10AIK @ WS 2012 Coupling (Kopplung) »Der Grad zu welchem die Klassen voneinander Abhängig sind »Eine hohe Kopplung ist schlecht für die Wartbarkeit der Software »Abhängigkeiten entstehen durch Methodenaufrufe, Vererbung und Zugriff auf öffentliche Attribute

60 60 TIT10AIK @ WS 2012 Cohesion (Kohäsion) »Misst, wie stark verwandt oder fokussiert die Aufgaben eines Elementes (Klasse) sind Klasse m1m2m3m4 Methoden a1 a2 Attribute Attribut- Zugriff

61 61 TIT10AIK @ WS 2012 Cohesion (Kohäsion) »Je höher die Kohäsion, desto weniger abgetrennte Bereiche gibt es in einer Klasse »Die Wahrscheinlichkeit, dass eine Klasse mit hoher Kohäsion genau nur einen Zweck erfüllt, ist hoch »Eine größtmögliche Kohäsion ist anzustreben

62 62 TIT10AIK @ WS 2012 McCabe-Metrik (Cyclomatic Complexity) »Misst die Komplexität von Kontrollflüssen in Methoden »Bestimmt den Aufwand, der benötigt wird, die Methode zu testen »Lange Methoden sind nicht unbedingt komplex »Methoden mit einer hohen Cyclomatic Complexity sind schwerer zu warten »Berechnung basierend auf das Aktivitätsdiagramm »CC( method ) = E – N + 2 »E: Anzahl der Kanten im Diagramm »N: Anzahl der Knoten im Diagramm

63 63 TIT10AIK @ WS 2012 McCabe - Beispiele CC( method ) = E – N + 2 CC = 1 - 2 + 2 = 1CC = 4 - 4 + 2 = 2CC = 2 - 3 + 2 = 1

64 64 TIT10AIK @ WS 2012 McCabe - Verzweigungen »Zu Verzweigungsknoten werden Keywords, die den Kontrollfluss ändern können »if, for, while, case, catch,&&, ||, ?, else if »Die folgenden Keywords erhöhen die Komplexität nicht »try, switch, else, default, finally

65 65 TIT10AIK @ WS 2012 McCabe – Method Returns... void test() {...... if(... ) if(... ) { return; return; }...... return; return;} CC(X) = E-N+2 = 3-3+2 = 3-3+2 = 2 = 2 Es gibt 2 Pfade! McCabe sieht nur je einen Start- und Endpunkt vor. Andere Endpunkte werden zum Ersten zurückgeführt.

66 66 TIT10AIK @ WS 2012 McCabe – Method Returns - Begründung... CALL FUNCNEXT STMT CC(X) = E-N+2 = 6-6+2 = 6-6+2 = 2 = 2 Es gibt 2 Pfade!

67 67 TIT10AIK @ WS 2012 McCabe-Metrik »Eine gewisse Komplexität ist normal und kann nicht vermieden werden »Es ist utopisch, nur Methoden mit einer zyklomatischen Komplexität von 2 zu haben »Methoden mit einer Komplexität > 10 sollten jedoch betrachtet werden »Ein Continuous Integration System kann diesen Wert überwachen

68 68 TIT10AIK @ WS 2012 Wie kann ich das alles überblicken? »Continuous-Integration-Systeme wie Jenkins können kontinuierlich Tests auf Coding Guideline Violations durchführen »Der Entwickler wird direkt nach dem Commit über das Verletzungen der Richtlinien informiert

69 69 TIT10AIK @ WS 2012 http://jenkins-ci.org/ Prüft kontinuierlich auf Code-Qualität und Erfolg der Unit-Tests


Herunterladen ppt "1 WS 2012 Software-Engineering II Refactoring."

Ähnliche Präsentationen


Google-Anzeigen