
Um Code Smells und ihre Behebung mittels Refactorings geht es in der einhundertsiebenundvierzigsten Episode des Anwendungsentwickler-Podcasts.
Podcast: Play in new window | Download (Duration: 55:44 — 26.2MB)
Abonnieren: Apple Podcasts | Spotify | RSS
Inhalt
- Was ist ein Code Smell?
- Smells sind Indikatoren für Code, der überarbeitungswürdig ist.
- Man erkennt sie anhand verschiedener Muster (z.B. lange Methoden).
- Die Smells können mit Refactorings überarbeitet und (hoffentlich) eliminiert werden.
- Nicht alle Smells sind immer schlecht. Sie dienen nur als Anhaltspunkt, noch einmal über den Code nachzudenken.
- Woher kommt der Name Code Smell?
- Kent Becks Oma wird das Zitat „If it stinks, change it.“ zugesprochen, das sich auf das Wechseln von Windeln bei Babys bezieht.
- Kent Beck hat diese Idee auf Code übertragen: Wenn der Code seltsam „riecht“, sollte man ihn anpassen.
- Wobei helfen uns Code Smells?
- Mit Code Smells können wir Stellen im Code aufdecken, die problematisch sind, und diese überarbeiten. Dadurch wird der gesamte Code insgesamt „besser“.
- Die benannten Smells helfen uns durch eine gemeinsame Sprache bei der Diskussion mit anderen Entwicklern (ähnlich wie Design Pattern).
- Was können wir gegen Code Smells tun?
- Das Mittel gegen Code Smells sind die Refactorings.
- Im Buch von Martin Fowler* gibt es eine übersichtliche Tabelle, welche Refactorings gegen welche Smells helfen können.
- Sind Code Smells immer böse?
- Code Smells sind nur ein Anhaltspunkt für Optimierungen. Der Entwickler muss selbst entscheiden, ob der Smell schlecht ist.
- Einige Code Smells hängen zusammen und das Auflösen des einen (z.B. Introduce Parameter Object) führt zur Einführung eines anderen (z.B. Data Class).
- Welche Code Smells gibt es?
- Duplicate Code
- Doppelter Code führt bei Änderungen schnell zu Fehlern, weil zu ändernde Stellen übersehen werden.
- Refactorings: Extract Method, Pull Up Method
- Comments
- Kommentare können helfen, den Code zu verstehen, aber häufig sind sie überflüssig und können durch sprechendere Bezeichner komplett eliminiert werden.
- Refactorings: Extract Method, Rename Method
- Long Method
- Lange Methoden sind schwieriger zu verstehen, zu testen und anzupassen.
- Refactorings: Extract Method
- Large Class
- Zu große Klassen machen häufig mehr als sie sollen und verletzen das Single Responsibility Principle. Das macht sie u.a. schwer testbar.
- Refactorings: Extract Class, Extract Subclass
- Long Parameter List
- Viele Parameter bei Methoden deuten darauf hin, dass diese zu viele Aufgaben übernehmen. Sie machen die Methoden schwer testbar und schwer verständlich. Außerdem müssen die Parameterlisten tendenziell oft angepasst werden.
- Refactorings: Replace Parameter with Method, Introduce Parameter Object
- Feature Envy
- Wenn Methoden oder Klassen sich viele Informationen „besorgen“ müssen, bevor sie ihren Job machen können, ist das ein Zeichen dafür, dass die Komponenten besser an einer anderen Stelle aufgehoben wären.
- Refactorings: Move Method
- Data Clumps
- Wenn verschiedene Daten immer zusammen herumgereicht werden (z.B.
Startdatum
undEndedatum
), ist das ein Zeichen für eine fehlende Abstraktion (z.B.Zeitraum
). - Refactorings: Introduce Parameter Object, Extract Class
- Wenn verschiedene Daten immer zusammen herumgereicht werden (z.B.
- Primitive Obsession
- Die Scheu vor eigenen kleinen Klassen führt oft dazu, dass doppelter Code entsteht und eine gute Kapselung verhindert wird.
- Refactorings: Replace Data Value with Object, Extract Class, Introduce Parameter Object
- Switch Statements: Gleiche Fallunterscheidungen werden häufig an mehreren Stellen benötigt und führen zu doppeltem Code, der mit Polymorphie verhindert werden könnte.
- Divergent Change: Einzelne Klassen müssen aufgrund von verschiedenen Änderungen angepasst werden.
- Shotgut Surgery: Aufgrund einer einzelnen Änderung müssen verschiedene Klassen angepasst werden.
- Parallel Inheritance Hierarchies: Sonderform von Shotgun Surgery, die das parallele Anlegen von Subklassen in verschiedenen Hierarchien erfordert.
- Lazy Class: Zu kleine Klassen, die keinen erkennbaren Mehrwert haben, sollten abgelöst werden.
- Speculative Generality: Anstatt alle möglichen zukünftigen Entwicklungen zu antizipieren, sollte besser das Prinzip You Ain’t Gonna Need It befolgt werden.
- Temporary Field: Instanzvariablen sollten nicht nur während der Laufzeit einzelner Methoden verwendet werden.
- Message Chains: Objekte, die Objekte aufrufen, die wieder Objekte aufrufen, wissen zu viel über die fremde Implementierung und sind damit stark gekoppelt. Das verletzt das Law of Demeter.
- Middle Man: Zu viel Delegierung ist auch nicht gut.
- Inappropriate Intimacy: Klassen sollten nicht zu viele Details anderer Klassen kennen.
- Alternative Classes with Different Interfaces: Gleiche Dinge sollten auch gleich benannt sein.
- Incomplete Library Class: Wenn Librarys nicht alles tun, was wir brauchen, sollten wir sie ergänzen, anstatt alles neu zu entwickeln.
- Data Class: Die guten alten POJOs oder Java Beans. Sie verhindern häufig saubere Kapselung und haben bei fehlender Geschäftslogik evtl. gar keine Daseinsberechtigung.
- Refused Bequest: Wenn Subklassen Teile ihres Vermächtnisses (geerbte Member) nicht nutzen wollen oder können, ist vielleicht die Hierarchie falsch gewählt.
- Duplicate Code
Literaturempfehlungen
Eine sehr schöne Liste möglicher Code Smells und ihrer Auswirkungen gibt es im Klassiker Refactoring von Martin Fowler*.
Links
- Permalink zu dieser Podcast-Episode
- RSS-Feed des Podcasts
- Code Smells
- Catalog of Refactorings
- Refactoring and Design Patterns
Neueste Kommentare