Code Smells und Refactorings – Anwendungsentwickler-Podcast #147

Um Code Smells und ihre Behebung mittels Refactorings geht es in der einhundertsiebenundvierzigsten Episode des Anwendungsentwickler-Podcasts.

Probeabo bei Audible (Affiliate)

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 und Endedatum), ist das ein Zeichen für eine fehlende Abstraktion (z.B. Zeitraum).
      • Refactorings: Introduce Parameter Object, Extract Class
    • 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.

Literaturempfehlungen

Eine sehr schöne Liste möglicher Code Smells und ihrer Auswirkungen gibt es im Klassiker Refactoring von Martin Fowler*.

Martin Fowler - Refactoring: Improving the Design of Existing Code (Affiliate)*

Links

Stefan Macke
Polyglot Clean Code Developer
Über den Autor
Ausbildungsleiter für Fachinformatiker Anwendungsentwicklung und Systemintegration, IHK-Prüfer und Hochschuldozent für Programmierung und Software-Engineering.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax