Code-Smells der Gruppe Confusers führen dazu, dass der Leser des Source-Codes verwirrt ist oder den Code falsch versteht und somit Fehler macht. Confosers führen im besten Fall dazu, dass der Leser länger braucht, den Inhalt zu verstehen und ggf. Erweiterungen zu machen, im schlechtesten Fall führen sie aber dazu, dass Bugs entstehen oder diese schwierig bis gar nicht gefunden werden.
Magic Number / Magic String
Beschreibung
Die Bedeutung einer Zahl, eines Werts oder eines Strings ist nicht klar. Dies Verwirrt den Leser und führt zu Missverständnissen.
Beispiel:
Schlechter Code | Guter Code |
Color c = new Color(„A“);
string s = „xyz“;
int i = 42; |
Color blueColor = Color.FromName(„Blue“);
int maxNumberOfItems = 42;
string DocumentIdentification = „xyz“; |
Warum ist der Source-Code schlecht?
Magic Numbers und Magic Strings machen den Code unleserlich und nicht gerade selbsterklärend. Zukünftige Software-Engineers verstehen den Source-Code nicht und fragen sich warum ein gewisser Wert gewählt wurde.
Wie wird man den Code-Smell los?
Führe erklärenden lokale Variablen oder Konstanten. Nutze explizite Werte nicht nur für das Setzen der Variablen, sondern auch für Tests. Die Tests führen zum besseren Verständnis des Lesers, es ist vor allem auch wichtig, dass Tests einen sprechenden Testnamen haben.
Wie entsteht der Code Smell?
Der Ersteller des Codes berücksichtigt nicht wie wichtig es ist Ausdrücke und Variablen klar und verständlich für den Leser zu machen. Code wird immer öfter gelesen als er bearbeitet wird. Deswegen sollte Code immer möglichst so geschrieben werden; dass er leicht zu lesen und zu verstehen ist. Oft denkt der Software-Engineer beim Schreiben des Codes auch nur an den zu implementierenden Code (Wie) nicht aber an eine höhere Abstraktionsebene der Domäne (Warum).
Wann ist es OK?
Bei einfachen Konstanten oder bei Bezeichnungen die von der Domäne verlangt werden. In Logfiles ist es ebenfalls notwendig, dass Ausdrücke 1:1 abgebildet werden.
Complicated Boolean Expression
Beschreibung
Es werden mehrere logische Boolean-Operationen werden hintereinander gereiht sodass sie schwierig zum Verstehen sind. Vor allem ineinander verschachtelte Verneinungen mit vielen Variablen sind für Menschen schwer zu verstehen.
Beispiel:
Schlechter Code | Guter Code |
if( a != (x && (!v || (z > k))))
{ … } |
int gearThreshold = z;
bool chosenGearLessThanThreshold = k < gearThreshold; bool currentActive = x; bool eMotorActive = (!v || chosenGearLessThanThreshold); if( a != (currentActive && eMotorActive) { … } |
Warum ist der Source-Code schlecht?
Verneinungen und doppelte (oder Mehrfach-)Verneinungen sind immer schlecht. Sie machen den Ausdruck richtig schwer zu verstehen. Lang boolsche Ausdrücke müssen mühsam analysiert und zerdröselt werden bevor sie der Leser versteht.
Wie wird man den Code-Smell los?
Lange ausdrücke in mehrere kleine Ausdrücke zerkleinern und sprechende Variablennamen verwenden. Doppelverneinungen auflösen.
Wie entsteht der Code Smell?
Der Source-Code und die beinhaltenden Ausdrücke wachsen mit der Zeit, weil neue Anforderungen hinzukommen und der Software-Engineer mit der Zeit mehr über die Anforderungen und das System lernt. Es kann auch vorkommen, dass boolsche Ausdrücke von anderen Personen entwickelt werden und der Software-Engineer diese 1:1 in den Code übernimmt. Der Software-Engineer sollte immer verstehen was er macht und somit diese Ausdrücke hinterfragen und vereinfachen und lesbar machen, nur dann kann er Verantwortung für den Code übernehmen und eine spätere Wartung gewährleisten.
Wann ist es OK?
Wenn komplexe Gleichungen außerhalb des Teams entstanden sind und Best-Practice sind, und deine Vereinfachung und ein lesbar machen nicht möglich sind, kann es OK sein einen langen boolschen Ausdruck im Code zu haben.
Inconsistent Solution
Beschreibung
Eine inkonsistente Lösung besteht dann, wenn der Software-Engineer oder das Software-Engineering-Team ein und das selbe Problem auf mehrere verschiedenen Arten löst. Ein bekanntes einfaches Beispiel für diesen Code-Smell ist der Umgang mit Strings. Hier werden zum Beispiel teilweise String mit Intager konkateniert teilweise StringBuilder.append() und teilweise String.format() verwendet, um Strings zusammenzubauen. Vor allem bei Logging-Operationen wird hier eine Mixtur an String-Operationen verwendet, weil es „eh nur ums Logging“ geht.
Beispiel:
Schlechter Code | Guter Code |
void LogError(String message, Exception ex)
{ Logger.Error($“The following Error accured: {message}, Ex: {ex.Message}“); } void LogWarn(String message, Exception ex) { Logger.Warn(„The Warning “ + message + „,was raised See Exceptoin: “ + ex.Message); } bool LogDebug(String message, Exception ex) { Logger.Debug(string.Format(„Debug Message : {0}, for {1}“, message, ex.Message)); } |
void LogError(String message, Exception ex)
{ Logger.Error($“The following Error accured: {message}, Ex: {ex.Message}“); } void LogWarn(String message, Exception ex) { Logger.Warn($“The following Warning was logged: {message}, Ex: {ex.Message}“); } bool LogDebug(String message, Exception ex) { Logger.Debug($“The following Message was logged: {message}, Ex: {ex.Message}“); } |
Warum ist der Source-Code schlecht?
Gibt es viele verschiedene Lösungen zum selben Problem, so variieren diese meist im Detail. Dies führt zu stark gestiegener Komplexität und ist fehleranfällig, weil vielleicht nicht jeder Software-Engineer alle Lösungsansätze mit Variationen kennt.
Wie wird man den Code-Smell los?
In erster Linie muss sich jeder diesem Problem bewusst sein. Dem Team sollte eine gemeinsame Verantwortung für den ganzen Source-Code bewusst sein. Mehrfach-Lösungen müssen gefunden, und ein gemeinsamer Weg vom Team definiert werden wie das Problem mit einer einzigen Lösung adressiert wird.
Wie entsteht der Code Smell?
Der Code-Smell entsteht, wenn kein Bewusstsein für die gemeinsam getragene Verantwortung beim Entwicklungs-Team vorherrscht und die Team-Mitglieder nicht oder zu wenig miteinander reden.
Wann ist es OK?
Inkonsistente Lösungen sollten nie akzeptiert werden. Sie deuten darauf hin, dass das Team redebedarf hat und enger zusammenarbeiten soll. Einigt euch auf einen Weg und dokumentiert ggf. den gemeinsamen Standard, den ihr einhalten wollt.
Bad Names
Beschreibung
Der Code-Smell „Schlechte Namen“ sind falsche, verwirrende, unvollständige Namen von Variablen, Konstanten, Methoden, Klassen, Modulen, Namespaces, …
Beispiel:
Schlechter Code | Guter Code |
//Ausflüchte
Helper, Manager, MISC, Tools, Utils, ConnectionManager, HelperDE, HelperEN,… //Unspezifische irrefürende und falsche Namen ten, t, x, first, last, missspelledWodrs different_CaseIng_or_wronG //Abkürungen und Akronyme mvc,AJX, VEL, //Namespaceing EmployeeAccount, EmployeeID, EmployeeAddress |
DatabaseConnection,
correctWords, CamelCaseNames namespace EmployeeAdministration { class Employee {} class Account {} class Address {} } |
Warum ist der Source-Code schlecht?
Der Name offenbart nicht die Bedeutung dessen wofür er steht oder ist so missverständlich, dass der Leser etwas anderes hineininterpretiert was nicht eigentliche Zweck entspricht. Dass führt dazu, dass andere Software-Engineers von falschen Annahmen ausgehen, oder sich mühsam in den Source-Code im Detail einlesen müssen. In diesen Fällen kann es dann vorkommen, dass Bugs entstehen oder Software-Engineers dazu verleitet sind ein Problem mehrfach zu lösen, weil sie die bereits bestehende Lösung nicht finden.
Wie wird man den Code-Smell los?
Am besten wird zur Beseitigung des Code-Scmells das „Change-Name“-Refectoring ausgeführt. Dazu sollte auf jeden Fall die Unterstützung eines professionellen Software-Engineering-Tools verwendet werden. Moderne IDEs bieten eine Rename-Funktion an. Des Weiteren ist es oft notwendig neue Variablen zu definieren und Klassen in neue Namespaces zu legen. Falsche Präfixe sollten eliminiert werden und ggf. in eigene Namespaces gesammelt werden.
Wie entsteht der Code Smell?
Bei diesem Code-Smell werden oft das Single Responsibility Principle und das Seperation of Concerns-Principle verletzt. Neue Funktionen und Features werden laufend zu bestehenden Klassen und Source-Code hinzugefügt und weichen somit bestehende Konzepte auf. Es kann auch sein, dass Programmierparadigmen wie Objekt-Orientierung nicht eingehalten wurden oder Coding-Standards ignoriert wurden oder nicht bewusst sind.
Wann ist es OK?
Schlechte Namen sollten nie akzeptiert werden. Das Wichtigste ist: Du solltest keine Kommentare verwenden, um schlechte Namen verständlich zu machen, viel besser ist es diese einfach umzunennen.
Flag Parameter
Beschreibung
Der Flag Parameter ist ein Code-Smell der das Verhalten einer Methode oder eines Objekts unberechenbar oder schwer verständlich macht. Es wird einer Methode oder einen Konstruktor ein Parameter mitgegeben. Dieser Parameter beeinflusst oder bestimmt dann das Verhalten der Methode oder sogar des gesamten Objekts.
Beispiel:
Schlechter Code | Guter Code |
class Transfomer
{ void TransformVoltage(bool useHighVoltage) { if (useHighVoltage) { // special high voltage code } else { //low voltage code } } } |
class Transfomer
{ void TransformVoltage() { //low voltage code } void TransformHighVoltage() { // special high voltage code } } oder abstract class Transfomer { abstract void transform(); } class HighVoltageTransformer : Transfomer { override void transform() { // special high voltage code } } class LowVoltageTransformer : Transfomer { override void transform() { // special low voltage code } } |
Warum ist der Source-Code schlecht?
Flag Parameter sind schlecht, weil sie zu Missverständnissen führen, den Source-Code unnötig komplexer machen und auch schlechter lesbar machen. Aus der Perspektive des Aufrufers kann das Verhalten oft nicht abgeschätzt werden und die Parameter können falsch eingestellt werden. Somit erhöhen sie die Fehleranfälligkeit und erschweren das Testen. Meist ist bei diesem Code-Smell das Single Responsibility Principle verletzt.
Wie wird man den Code-Smell los?
Um diesen Code-Smell los zu werden muss der Code refactored werden. Die Funktionalität der Methode muss in zwei Methoden aufgeteilt werden. Die Methodennamen müssen dementsprechend genauer sein und beschreiben welche Funktionalität abgedeckt wird. Bei Flags, die in Konstruktoren verwendet werden, muss das Flag in zwei statische Create-Methoden gekapselt werden und der Konstruktor privat gemacht werden. Eine bessere Variante ist es allerdings Objekt-Orientiert zu entwickeln und eine Klassen-Hierarchie aufzubauen.
Wie entsteht der Code Smell?
Der Flag Parameter Code-Smell entsteht, wenn sich ein Software-Engineer entweder nicht auskennt und z.B. noch Nachholbedarf mit Objekt-Orientierung hat oder wenn in der Eile Funktionalität zu einer Methode oder einer Klasse hinzugefügt wird. Diese Workarounds und Hacks sind allerdings tickende Zeitbomben, die sich früher oder später immer rächen, daher sollten sie nicht gemacht werden.
Wann ist es OK?
Der Flag Parameter Code-Smell sollte immer verhindert werden.
Output Parameter
Beschreibung
Beim Output Parameter Smell wird ein Parameter nur deswegen der Methode übergeben, um einen Wert aus der Methode heraus dem Aufrufer zurückzugeben. Der Parameter wird innerhalb der Methode nicht verwendet, trägt nicht zum Ablauf bei und ist daher nur der Transporteur.
Beispiel:
Schlechter Code | Guter Code |
private void GetCurrentVelocity(out Velocity currentVelocity)
{ // … } private bool TryParse(string value, out Velocity velocity) { //… } private bool TryParse(string value, out int VelocityInInt) { … } |
public Velocity CurrentVelocity()
{ get; } private Velocity TryParse(string value) { //… // throw Exception // or // return null } private int? TryParse(string value) { //… } |
Warum ist der Source-Code schlecht?
Output Parameter verletzen meist das Principle of least astonishment. Der Software-Engineer erwartet in einem Sauberen Source-Code nicht, dass Output Parameter verwendet werden. Es gibt mehrere Möglichkeiten, um keine Output Parameter zu brauchen. So können Exceptions geschmissen werden, Rückgabe-Objekte verwendet werden oder Null-Werte benutzt werden.
Es ist auch möglich, dass das Single Responsibility Principle verletzt wurde, wenn im Nachhinein noch Funktionalität hinzugefügt wurde und der Output Parameter als geeigneter Rückgabekanal fälschlicher weise gewählt wurde.
Wie wird man den Code-Smell los?
Je nachdem warum der Output Parameter entstanden ist, muss die geeignete Gegenmaßnahme ergriffen werden. Wurde der Output Parameter gewählt, um mehrere Rückgabemöglichkeiten zu haben, so kann mit einen Rückgabeobjekt Abhilfe geschaffen werden. Wurde der Output Parameter wie oben im TryParse Beispiel dazu verwendet, um noch gleichzeitig einen Wahrheitswert mitzugeben, um zu überprüfen oder der Parse funktioniert hat, so sollten Entweder Exceptions verwendet werden oder der wert Nullable gemacht werden. Sollte der Autor mit dem Output Parameter bezweckt haben, dass er die bestehende Methode um zusätzliche Funktionalität erweitert, so sollte die Methode zerteilt werden in die jeweiligen Kernfunktionalitäten.
Wie entsteht der Code-Smell?
Es gibt typischerweise zwei Ursachen für die Entstehung des Output Parameter Code-Smells oft wird solch ein Code von ehemaligen FORTRAN oder C Entwicklern produziert. In diesen Programmiersprachen wurde der Rückgabewert der Funktion für den Error-Code verwendet. Auf der anderen Seite gibt es als zweite Ursache Software-Engineers die in der Kürze der Zeit den Output Parameter als Hack oder Workaround verwenden, um zusätzliche Funktionalität in die Methode zu bekommen.
Wann ist es OK?
Output Parameter sollten in C# immer verhindert werden.
Deceiving Interface
Beschreibung
Beim Deceiving Intercace Smell ist dem Konsumenten des Interfaces nicht klar ob ein Parameter ein Eingabe- oder ein Ausgabeparameter ist. Dies führt zu Verwirrungen und ist eine mögliche Fehlerquelle.
Beispiel:
Schlechter Code | Guter Code |
void CalculateVelocity(List<int> input, List<int> output)
{ foreach (var item in input) { output.Add(item.distance / item.time); } } |
IList<int> CalculateVelocity(IEnumerable<int> input) { IList<int> output = new List<int>(); foreach (var item in input) { output.Add(item.distance / item.time); } return output; } |
Warum ist der Source-Code schlecht?
Da beim Deceiving Interface nicht klar ist, ob der Parameter ein Eingabe- oder ein Ausgabeparameter ist, und somit nicht klar ist ob der Parameter innerhalb der Methode manipuliert wird, ist das Verhalten der Methode nicht berechenbar. Es könnten somit unbekannte Side-Effects auftreten die der Aufrufende nicht erwartet.
Wie wird man den Code-Smell los?
Achte beim Schreiben von Klassen und Interfaces darauf, dass diese eindeutig sind und klar anzeigen wie ein Parameter genutzt wird.
Wie entsteht der Code-Smell?
Oft entsteht das Deceiving Interface, weil sich Entwickler nicht genug zeit nehmen, sich ein gutes Interface oder eine gute Klassendefinition zu erstellen. Dabei werden oft die Parameter vernachlässigt.
Wann ist es OK?
Deceiving Interfaces sollten immer verhindert werden.
Alle Code-Smells im praktischen eBook: F*ck it smells – Clean Code in C#
Weitere Blogs zum Thema Softwarequalität
Code-Smells: Object-Orientation Abusers |
Code-Smells: Couplers |
|
![]() |
![]() |
Weitere Buchempfehlungen
[Links zu Amazon]
![]() |
||
[Amazon 9,99€] | [Amazon 34,99 €] | [Amazon 24,95 €] |
[Amazon 34,00 €] | [Amazon 25,99 €] | [Amazon 42,00 €] |
Zum Autor:
David Theil aus Linz Oberösterreich ist Digitalisierungs-Coach, Software-Engineer und als Head of Software-Development für über 30 Softwareentwickler verantwortlich. Beruflich beschäftigt er sich bereits jahrelang mit der Digitalisierung und hat bereits bei vielen Digitalisierungs-Projekten in der Wirtschaft federführend mitgewirkt. Er bewegt sich in Themen wie Digitalisierung, IoT, oder Industrie 4.0 sowohl beratend als auch praktisch mit echten Lösungen.
https://www.xing.com/profile/David_Theil
https://www.linkedin.com/in/david-theil-1a4190148/
https://www.linkedin.com/groups/8678887