Code-Smell
# Code-Smell

Unter Code-Smell, kurz Smell (engl. ‚[schlechter] Geruch‘) oder deutsch übelriechender Code versteht man in der Programmierung ein Konstrukt, das eine Überarbeitung des Programm-Quelltextes nahelegt. Dem Vernehmen nach stammt die Metapher Smell von Kent Beck und erlangte weite Verbreitung durch das Buch Refactoring von Martin Fowler. Unter dem Begriff sollten handfestere Kriterien für Refactoring beschrieben werden, als das durch den vagen Hinweis auf Programmästhetik geschehen würde.

Bei Code-Smell geht es nicht um Programm- oder gar Syntaxfehler, sondern um funktionierenden Programmcode, der aber schlecht strukturiert ist. Das größte Problem liegt darin, dass der Code für den Programmierer schwer verständlich ist, so dass sich bei Korrekturen und Erweiterungen häufig wieder neue Fehler einschleichen. Code-Smell kann auch auf ein tieferes Problem hinweisen, das in der schlechten Struktur verborgen liegt und erst durch eine Überarbeitung erkannt wird.

## Verbreitete Smells

Die folgenden von Martin Fowler und Kent Beck beschriebenen Smells beziehen sich auf die objektorientierte Programmierung, haben aber naheliegende Entsprechungen unter anderen Programmier-Paradigmen.

### Code-Duplizierung

    Der gleiche Code kommt an verschiedenen Stellen vor.

### Lange Methode

    Eine Methode (Funktion, Prozedur) ist zu lang.

### Große Klasse

    Eine Klasse ist zu umfangreich, umfasst zu viele Instanzvariablen und duplizierten Code. Siehe auch Gottobjekt.

### Lange Parameterliste

    Anstatt ein Objekt an eine Methode zu übergeben, werden Objekt-Attribute extrahiert und der Methode als lange Parameterliste übergeben.

### Divergierende Änderungen

    Für eine Änderung muss eine Klasse an mehreren Stellen angepasst werden.

### Schrotkugeln herausoperieren (engl. Shotgun Surgery)

    Dieser Smell ist noch gravierender als divergierende Änderungen: Für eine Änderung müssen weitere Änderungen an vielen Klassen durchgeführt werden.

### Neid (engl. Feature Envy)

    Eine Methode interessiert sich mehr für die Eigenschaften – insbesondere die Daten – einer anderen Klasse als für jene ihrer eigenen Klasse.

### Datenklumpen

    Eine Gruppe von Objekten kommt häufig zusammen vor: als Felder in einigen Klassen und als Parameter vieler Methoden.

### Neigung zu elementaren Typen (engl. Primitive Obsession)

    Elementare Typen werden benutzt, obwohl auch für einfache Aufgaben Klassen und Objekte aussagekräftiger sind.

### Case-Anweisungen in objektorientiertem Code

    Switch-Case-Anweisungen werden benutzt, obwohl Polymorphismus sie weitgehend überflüssig macht und das damit zusammenhängende Problem des duplizierten Codes löst.

### Parallele Vererbungshierarchien

    Zu jeder Unterklasse in der einen Hierarchie gibt es immer auch eine Unterklasse in einer anderen Hierarchie.

### Faule Klasse

    Eine Klasse leistet zu wenig, um ihre Existenz zu rechtfertigen.

### Spekulative Allgemeinheit

    Es wurden alle möglichen Spezialfälle vorgesehen, die gar nicht benötigt werden; solch allgemeiner Code braucht Aufwand in der Pflege, ohne dass er etwas nützt.

### Temporäre Felder

    Ein Objekt verwendet eine Variable nur unter bestimmten Umständen – der Code ist schwer zu verstehen und zu debuggen, weil das Feld scheinbar nicht verwendet wird.

### Nachrichtenketten

    Das Gesetz von Demeter wird verletzt.

### Middle Man (Vermittler)

    Eine Klasse delegiert alle Methodenaufrufe an eine andere Klasse.

### Unangebrachte Intimität

    Zwei Klassen haben zu enge Verflechtungen miteinander.

### Alternative Klassen mit verschiedenen Schnittstellen

    Zwei Klassen machen das gleiche, verwenden hierfür aber unterschiedliche Schnittstellen.

### Inkomplette Bibliotheksklasse

    Eine Klasse einer Programmbibliothek benötigt Erweiterungen, um in einem für sie geeigneten Bereich verwendet werden zu können.

### Datenklasse

    Klassen mit Feldern und Zugriffsmethoden ohne Funktionalität.

### Ausgeschlagenes Erbe (engl. Refused Bequest)

    Unterklassen brauchen die Methoden und Daten gar nicht, die sie von den Oberklassen erben (siehe auch Liskovsches Substitutionsprinzip)

### Kommentare

    Kommentare erleichtern im Allgemeinen die Verständlichkeit. Kommentare erscheinen jedoch häufig genau dort notwendig zu sein, wo der Code schlecht ist. Kommentare können somit ein Hinweis auf schlechten Code sein.

### Weitere Smells und Programmierungs-Anti-Pattern

Neben den von Fowler erwähnte Smells gibt es noch eine Reihe von Code-Smells die oft auch unter Programmierungs-Anti-Pattern erwähnt werden:

**Nichtssagender Name (engl. Uncommunicative Name)**


    Name, der nichts über Eigenschaften oder Verwendung des Benannten aussagt. Aussagekräftige Namen sind wesentlich für das Verständnis von Programmcode.

**Redundanter Code**


    Ein Stück Code, das nicht (mehr) verwendet wird.

**Exhibitionismus (engl. Indecent Exposure)**


    Interne Details einer Klasse sind unnötigerweise Teil ihrer Schnittstelle nach außen.

**Contrived complexity (engl.)**


    Erzwungene Verwendung von Entwurfsmustern, wo einfacheres Design ausreichen würde.

**Zu lange Namen**


    Insbesondere die Verwendung von Architektur- oder Designbestandteilen in den Namen von Klassen oder Methoden.

**Zu kurze Namen**


    Die Verwendung von „x“, „i“ oder Abkürzungen. Der Name einer Variable sollte ihre Funktion beschreiben.

**Über-Callback**


    Ein Callback, der versucht, alles zu tun.

**Komplexe Verzweigungen**


    Verzweigungen, die eine Menge von Bedingungen abprüfen, die mit der Funktionalität des Codeblocks nichts zu tun haben.

**Tiefe Verschachtelungen**


    Verschachtelte if/else/for/do/while-Statements. Sie machen den Code unlesbar.

## Architektur-Smells

Neben den von Beck und Fowler adressierten Smells im Quelltext von Anwendungen treten Smells auch in der Architektur von Softwaresystemen auf. Diese wurden von Stefan Roock und Martin Lippert beschrieben.

Zu den Architektur-Smells zählen unter anderem:

* Zyklische Benutzungsbeziehungen zwischen Paketen, Schichten und Subsystemen
* Größe und Aufteilung der Pakete oder Subsysteme
