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
Servus Stefan, ich bin vor ca. einem halben Jahr durch Zufall auf dein Podcast gestoßen und mir mittlerweile bestimmt über 50 Folge angehört. Vor allem abstrakte Themen wie Pattern oder spezielle Themen wie „Zeichensätze“ oder allgemeine Tipps rund um CleanProgramming waren für mich echt wertvoll. Gerade beim Thema CleanProgramming ist man eigentlich nie ausgelernt – da kann man vom neuen Wissen nur profitieren.
Großen Dank für deine Inhalte! Ich freue mich auf neue Folgen
Viele Grüße
Anton
Hallo Anton, danke für dein Feedback. Das freut mich! 🙂