Bára Bühnová: Naučte se taktizovat s pomocí bad code smells a quality tactics
Bad Code Smells - Philipps-Universität Marburg · Was sind Bad Code Smells? ... "An exploratory...
Transcript of Bad Code Smells - Philipps-Universität Marburg · Was sind Bad Code Smells? ... "An exploratory...
Bad Code Smells
20. Mai 2015
Taentzer Softwarequalität 2015 84
Überblick
Was sind Bad Code Smells? Welche Arten von Bad Code Smells gibt es?
klasseninterne klassenübergreifende
Welche Werkzeuge zur Analyse von Bad Code Smellsgibt es?
Taentzer Softwarequalität 2015 85
Was sind Bad Code Smells? Anrüchige (verdächtige) Code-Stellen Hier lohnt es sich, genauer hinzuschauen. Sollten eventuell durch Refactoring-Maßnahmen restrukturiert
werden. Kondensierung von Erfahrungswissen Syntaktische Prüfung von Programmcode hinsichtlich
bestimmter Muster Analytische Qualitätssicherungsmaßnahme für
bessere Wartbarkeit bessere Erweiterbarkeit geringere Fehleranfälligkeit
Überblick über Bad Code Smells in [Fowler].
Taentzer Softwarequalität 2015 86
Klasseninterne Bad Smells
doppelter Code lange Methoden lange Parameterlisten viele Änderungen einer Klasse temporäre Felder sich wiederholende Switch-Anweisungen Kommentare
Taentzer Softwarequalität 2015 87
Doppelter Code
einer der häufigsten Bad Code Smells gleicher oder sehr ähnlicher Code, der mehrfach
auftritt Hauptgrund: Copy-and-Paste-Programmierung
schnelle Wiederverwendung von Code
Beispiele: derselbe Codeblock in zwei Methoden derselben Klasse oder in zwei Unterklassen einer gem. Oberklasse oder in zwei komplett verschiedenen Klassen
Taentzer Softwarequalität 2015 88
Beispiel: Doppelter Code
void printInformation() { printTitle(); //print details System.out.println ("name: " + name); System.out.println („address: " + getAddress());
}
void printAddressBook() { for(int i = 1; i <= book.length; i++) { //print address System.out.println ("name: " + book[i].name); System.out.println („address: " + book[i].getAddress());}
}
Taentzer Softwarequalität 2015 89
Lange Methoden
Vermeidung von „Spaghetti-Code“
Je länger eine Methode, desto fehleranfälliger
Wiederverwendung von Codefragmenten wird nicht ermöglicht.
Statt Kommentierung von Codeblöcken, besser den Block als Methode rausziehen
Prinzipielles Vorgehen: Codeblöcke identifizieren nötige Parameter und
temporäre Variablen identifizieren
komplexe Bedingungen zerschlagen
Lange Methode
Taentzer Softwarequalität 2015 90
//…
//…
//…
Originalmethode mitvielen Codezeilen
Codeblöcke identifizieren, die in einzelne Methoden ausgelagert werden
Taentzer Softwarequalität 2015 91
Lange Parameterlisten
Lange Parameterlisten erschweren das Verständnis von Methodenaufrufen.
Sind Parameter besser als globale Variablen?
Einsparen von Parametern: Verwendung von
Objektanfragen Verwendung von
Parameterobjekten
Beispiel:
Wann könnten lange Parameterlisten gewollt sein?
CalendarinsertAppointment(start: Time, end: Time)showAppointments(start: Time, end: Time)cancelAppointments(start: Time, end: Time)
Taentzer Softwarequalität 2015 92
Viele Änderungen einer Klasse
Verschiedene Änderungs-wünsche führen zu Änderungen derselben Klasse.
Beispiel für verschiedene Änderungen einer Klasse: Änderung einer
Datenzugriffsklasse, falls sich die Datenbank ändert
Codeänderungen, wenn sich Geschäftsregeln ändern
Einfügen neuer Aspekte (Z.B. wird ein Logging-Mechanismus eingeführt.)
Beispiel: eine Klasse, die zu viele
verschiedenartige Felder hat
Personname: Stringbirthday: Dateposition: PositionTypephone: intfax : intstreet: Stringzip: intcity: String
Taentzer Softwarequalität 2015 93
Temporäre Felder
Felder einer Klasse beschreiben die Zustände ihrer Objekte.
Manchmal sind Felder nur zeitweise gesetzt.
Zur Vermeidung von langen Parameterlisten werden Felder erzeugt.
Beispiel:
PhoneBooksearchResult: intsearchNumber()
Phonenumber: int
1
*
Taentzer Softwarequalität 2015 94
Kommentare und sich wiederholende Switch-Anweisungen
Switch-Anweisungen: Häufig ähnliche Switch-
Anweisungen an mehreren Stellen im Code
Besser eine Switch-Anweisung in eine eigene Methode extrahieren
Kommentare: Kommentare sind an sich
nichts Schlechtes. Im Gegenteil: Sie sind gut! Manchmal weisen
Kommentare auf schlechten Code hin.
Kruder Code soll durch Kommentare verständlicher werden.
Beispiel: Sich wiederholende Switch-Anweisungen
class Article {private int category;
public static int getPrize() {switch(category){
case `Shoes´: …case `Underwear´: …
}}
Taentzer Softwarequalität 2015 95
public static int getName() {switch(category){
case `Shoes´: …case `Underwear´: …
}}
Taentzer Softwarequalität 2015 96
Klassenübergreifende Bad Smells
große Klassen Änderungen in vielen verschiedenen Klassen
aufgrund von einem Änderungswunsch Methoden, die zuviel auf andere zugreifen Datenhaufen faule Klassen Nachrichtenketten verweigertes Erbe auf Verdacht allgemein gehaltener Code
Taentzer Softwarequalität 2015 97
Große Klassen
meist zu viele Felder Redundanzen innerhalb der
Klasse vermeiden „Turn five 100 line methods
into five 10 line methodswith another ten 2 linemethods extracted from theoriginal.“
Szenarien: Manche Felder lassen sich
gut in neuen Objektklassen zusammenfassen.
Bei zu viel Code: Methoden herausziehen,
durch Verkürzung der Methoden redundanten Code finden
Herausziehen von Schnittstellen kann aufzeigen, wie eine Klasse in mehrere Klassen zerlegt werden kann.
Konvertierung von Konstanten in Aufzählungstypen
Taentzer Softwarequalität 2015 98
Beispiel:Große
Klassen
vorher
Taentzer Softwarequalität 2015 99
Beispiel: Große Klassen
nachher
Taentzer Softwarequalität 2015 100
Änderung viele Klassen betreffend
Ein Änderungswunsch, der viele Klassen betrifft.
Änderungsstellen sind schwer zu finden, es kann schnell eine vergessen werden.
Klassenstruktur semantisch nicht passend
Manchmal ist die Änderung vieler Klassen bei einem Änderungswunsch auch gewollt. Wann?
Copy-and-Paste-Programmierung: schnelle
Wiederverwendung Wenn der Code
anschließend stark modifiziert wird, ist Copy-and-Paste adäquat.
Boredom-Is-A-Smell: dieselben Einträge bei
vielen Klassen
Taentzer Softwarequalität 2015 101
Methoden, die zuviel auf Daten anderer Klassen zugreifen
Der Fokus einer Klasse sind ihre Daten.
verdächtig: eine Methode, die mehr auf Daten anderer Klassen zugreift
Eine Methode sollte zu der Klasse gehören, deren Daten sie überwiegend verwendet.
class Room { Lecture[] lectures;
}
class Lecture { int id; boolean roomUsed(Room r) {
for(int i= 0; i < r.lectures.length; i++){if (r.lectures[i].id == id)
return(true); } return(false);
} }
... if (l.isInRoom(r)) ...
Taentzer Softwarequalität 2015 102
Datenhaufen und faule Klassen
Datenhaufen: Oft hängen mehrere Daten
zusammen. Wenn Daten immer
gemeinsam auftreten → neue Datenklassen
Welche Vor- und Nachteile bringen neue Datenklassen?
Datenklassen müssen noch mit Funktionalität angereichert werden.
Faule Klassen: Klassen mit zu wenig
Funktionalität mögliche Gründe:
zu ausgeprägte Klassen-hierarchie
reine Datenklassen
Taentzer Softwarequalität 2015 103
Beispiel 1: Bad Code Smells
vorher
Taentzer Softwarequalität 2015 104
Beispiel 1: Bad Code Smells
nachher
Taentzer Softwarequalität 2015 105
Beispiel 2: Bad Code Smells
vorher
Taentzer Softwarequalität 2015 106
Beispiel 2: Bad Code Smells
nachher
Taentzer Softwarequalität 2015 107
Beispiel 3: Bad Code Smells
vorher
Taentzer Softwarequalität 2015 108
Beispiel 3: Bad Code Smells
nachher
Taentzer Softwarequalität 2015 109
Nachrichtenketten
Kaskaden von Methoden-aufrufen sind verdächtig.
Einkapselung geht häufig mit Delegation einher.
Wenn eine Klasse die meisten seiner Methoden-aufrufe an eine andere Klasse delegiert, kann sie eliminiert werden.
Zwei Klassen, die zu stark miteinander kommunizieren, sind verdächtig.
Beispiel: getPerson(i).getAddress().
getStreet().getHouseNumber().print();
PersongetAddress()
AddressgetStreet()getCity()
Street City
Taentzer Softwarequalität 2015 110
Verweigertes Erbe
Subklassen, die zu wenige Methoden und Felder von ihren Elternklassen verwenden
Schnittstellen sollten immer wiederverwendet werden.
Methodenrümpfe müssen nicht wiederverwendet werden.
Verdächtig: Eintrag ist nur für eine Schwesterklasse interessant.
Bei Verdacht: Vererbung durch Delegation ersetzen
Beispiele:
Personmatrikelnr: int
Student Dozent
List Stack
Taentzer Softwarequalität 2015 111
Auf Verdacht allgemein gehaltener Code
Code für alle Eventualitäten abstrakte Klassen, die nicht
viel Funktionalität enthalten Parameter, die nicht
gebraucht werden Code, der nur in Test-
klassen verwendet wird
Beispiele: Methodenname reicht nicht,
um den Inhalt zu verstehen Eine Methode wird immer mit
dem gleichen Wert aufgerufen.
Abstrakte Klasse mit nur einer Unterklasse
Template, das mit nur einem Argumenttyp sinnvoll ist
Taentzer Softwarequalität 2015 112
Code Smell Metriken
Umfangsmetriken Methoden mit mehr als 20 Code-Zeilen, mehr als 3
Parameter oder mehr als 2 Ebenen tief Klassen mit mehr als 10 öffentlichen Methoden und einigen
wenigen privaten Methoden
Namensgebung schlechte Namen für Klassen, Methoden oder Variablen
doppelte Code-Fragmente nicht durch Tests abgedeckte Code-Fragmente
Taentzer Softwarequalität 2015 113
Werkzeuge
Werkzeuge, mit denen man Bad Code Smellsentdecken kann: CodePro AnalytiX Eclipse Plugin Metrics Eclipse Plugin Checkstyle Eclipse Plugin PMD ...
Da Code Smells projektspezifisch eingestellt werden sollten, erlauben diese Werkzeuge auch die Spezifikation der aktiven Smells.
Empirische Studien zu Bad Code Smells
Klassen mit Bad Smells werden öfter geändert als andere und können die Weiterentwicklung behindern. [KPG09]
Verbesserungen am Sourcecode sollten auf der Basis von Code Smells und persönlichen Einschätzungen vorgenommen werden. [ML06]
Gottklassen sind Klassen, die viel Intelligenz des Systems enthalten, eine hohe Komplexität haben und viele Daten anderer Klassen nutzen. Gottklassen werden öfter als andere geändert. Werden sie aber bzgl. ihrer Größe normalisiert, tritt eher ein gegenteiliger Effekt auf. [OCS10]
Ein Smell ist noch kein Problem, aber mehrere. [AKG+11] Automatische Smell-Erkennung hilft beim Code-Review. [SZS+10]
Taentzer Softwarequalität 2015 114
Taentzer Softwarequalität 2015 115
Zusammenfassung Qualitätssicherungsmaßnahme für
Besser Lesbarkeit des Codes bessere Wartbarkeit geringere Fehleranfälligkeit
Ziel der Analyse durch Bad Code Smell: Vermeidung von Coderedundanzen: „Once and only once“ bessere Strukturierung des Codes Auffinden von ungenutzten Codeanteilen
Zwei Arten des Code Review: pragmatisch: Code Smells werden von Fall zu Fall
angesehen und eventuell eliminiert. puristisch: Alle Code Smells werden eliminiert.
Werkzeuge können automatisch verdächtige Code-Stellen finden.
Literatur [Fowler] M. Fowler: Refactoring: Improving the Design of Existing
Code, Addison-Wesley, 1999 [KPG09] Khomh, Foutse, Massimiliano Di Penta, and Y. Gueheneuc.
"An exploratory study of the impact of code smells on software change-proneness." Reverse Engineering, 2009. WCRE'09. 16th Working Conference on. IEEE, 2009. http://www.rcost.unisannio.it/mdipenta/papers/wcre2009-smells.pdf
[ML06] Mäntylä, Mika V., and Casper Lassenius. "Subjective evaluation of software evolvability using code smells: An empirical study." Empirical Software Engineering 11.3 (2006): 395-431. http://link.springer.com/article/10.1007/s10664-006-9002-8/fulltext.html
[OCS10] Olbrich, Steffen M., Daniela S. Cruzes, and Dag IK Sjoberg. "Are all code smells harmful? A study of God Classes and Brain Classes in the evolution of three open source systems." Software Maintenance (ICSM), 2010 IEEE Int. Conference on. IEEE, 2010. http://www.idi.ntnu.no/grupper/su/publ/daniela/OlbrichCodeSmells-CameraReady.pdf
Taentzer Softwarequalität 2015 116
Literatur [AKG+11] Abbes, Marwen, et al. "An empirical study of the impact of
two antipatterns, blob and spaghetti code, on program comprehension." /Software Maintenance and Reengineering (CSMR), 2011 15th European Conference on/. IEEE, 2011. http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.294.1685&rep=rep1&type=pdf
[SZS+10] Schumacher, Jan, et al. "Building empirical support for automated code smell detection." /Proceedings of the 2010 ACM-IEEE International Symposium on Empirical Software Engineering and Measurement/. ACM, 2010. http://www.rose-hulman.edu/Users/faculty/ young/CS-Classes/OldFiles/csse575/Resources/a8-schumacher.pdf
Interessante Links: Code Smell Katalog: http://c2.com/cgi/wiki?CodeSmell The Catalog of Refactoring - Code Smell
https://refactoring.guru/catalog
Taentzer Softwarequalität 2015 117