Code-Smells – Couplers

Zu der Gruppe der Couplers – Code-Smells zählen all jene Code-Smells die dazu führen, dass eine starke Kopplung zwischen Komponenten entsteht. Gerade in der Objektorientierung sollte immer darauf geachtet werden lose gekoppelte Komponenten zu erzeugen, da ansonsten Änderungen aufgrund der gestiegenen Komplexität schwierig und fehleranfällig werden und dementsprechend die Weiterentwicklungs- und Wartungskosten steigen.

Inappropriate Intimacy

 

Beschreibung

In der objektorientierten Programmierung sollten Objekte nur das von einander wissen was wirklich notwendig ist. Bei einer Komposition von einer Klasse in einer anderen sollte die Komposition möglichst einfach austauschbar sein und die zwei Klassen möglichst lose gekoppelt. Das Inappropriate Intimacy Code-Smell verletzt genau dieses Grundprinzip. Die Hauptklasse verwendet Details der Komposition die es eigentlich nicht verwenden sollte. Besser wäre es, wenn es diese Details über eine öffentliche Schnittstelle zur Verfügung gestellt bekommen würde.

 

Beispiel:

Schlechter Code Guter Code
 

class ESP

{

public Angle angleOfWheels;

public CorrectionFactor CorrectionFactor;

}

 

class Car

{

private ESP carESP;

private double velocity;

private double triggerVelocity;

private Angle triggerAngle;

public virtual void DriveInCurve()

{

if(velocity > triggerVelocity && carESP.angleOfWheels > triggerAngle)

{

CorrectAngle(carESP.angleOfWheels, carESP.CorrectionFactor);

}

}

private void CorrectAngle(Angle a, CorrectionFactor f)

{

}

}

 

 

 

class ESP

{

private Angle angleOfWheels;

private CorrectionFactor CorrectionFactor;

private double triggerVelocity;

private Angle triggerAngle;

 

public void ControlAngleWhileDrive(double Velocity)

{

}

 

}

 

class Car

{

private ESP carESP;

private double velocity;

public virtual void DriveInCurve()

{

carESP.ControlAngleWhileDrive(velocity);

}

}

 

 

 

Warum ist der Source-Code schlecht?

Die starke Kopplung zwischen der Hauptklasse und der Komposition und vor allem die Freizügigkeit der Komposition, was seine Properties und öffentliche Schnittstellen angeht, führt dazu, dass sich Funktionalität auf beide Klassen ausweitet und es keine strikte Trennung dieser Funktionalität mehr gibt. Dies wiederum führt zu einer gestiegenen Komplexität und schwereren Verständlichkeit und Wartbarkeit des Sourc-Codes, was wiederum zu einer erhöhten Fehlerwahrscheinlichkeit führt. Es ist in diesen Fällen leichter möglich, dass nur die Eine Klasse aktualisiert wird, die Aufrufenden Klassen aber übersehen werden nachzuziehen und dementsprechend Bugs entstehen.

 

Wie wird man den Code-Smell los?

Die freizügige Klasse wird mittels Kapselung von Properties und dem Privatsetzen von Eigenschaft und Methoden verschlossen. Gegebenenfalls muss Funktionalität von der Hauptklasse in die Komposition gezogen werden. Es kann auch sinnvoll sein das kleinere Objekt im größeren zu integrieren und aufzulösen. Ein Adressbucheintrag kann beispielsweise ein Objekt Telefonnummer enthalten oder die Telefonnummer kann auch direkt als Eigenschaft (z.B. String) im Adressbucheintrag gehalten werden. Beide Klassen werden also zusammen-gemerged.

 

Wie entsteht der Code-Smell?

Dieser Code-Smell entsteht oft durch Unachtsamkeit des Software-Engineers, der freizügig mit der Kapselung von Klassen und Objekten umgeht. Meist kommen diese Software-Engineers von kleinen Teams oder haben bisher nur allein an Softwareprojekten oder Modulen in Softwareprodukten gearbeitet. Gerade in agilen Softwareprojekten mit Shared-Code-Ownership passieren dann aufgrund dieser Code-Smells dann Fehler. Andere Software-Engineers können dann diese Freizügigkeit ausnutzen mit teilweise sehr negativen Konsequenzen.

 

Wann ist es OK?

In C# und anderen Sprachen gibt es das Konzept von Inner-Classes diese inneren Klassen können naturgemäß intimer mit ihren Host-Klassen umgehen und ihre Daten, Methoden und Funktionalitäten teilen.

 

 

 

Feature Envy

 

Beschreibung

Der Funktions-Neid, so heißt das Code-Smell Feature Envy auf Deutsch, besteht wenn eine Klasse eine andere Klasse stark nachahmt, Funktionen ausnützt und erweitert und dabei sehr viele Methoden und Properties fast eins zu eins übernimmt. Anstatt die neue Funktionalität in die bereits bestehende Klasse zu integrieren, beneidet die neue Klasse die ältere für seine Funktionen und möchte diese am liebsten selbst haben und erweitern.

 

Beispiel:

Schlechter Code Guter Code
 

class FlightRoute

{

public Point Start { get; set; }

public Point End { get; set; }

 

 

}

 

class FlightLenghtCalculator

{

 

 

public double CalcFlightLen(FlightRoute

flight)

{

var deltaX = flight.End.X – flight.Start.X;

var deltaY = flight.End.Y – flight.Start.Y;

return Math.Sqrt(deltaX * deltaX + deltaY *

deltaY)

 

}

 

 

}

 

 

 

 

class FlightRoute

{

public Point Start { get; set; }

public Point End { get; set; }

 

 

 

public double CalcFlightLen()

{

var deltaX = End.X – Start.X;

var deltaY = End.Y – Start.Y;

return Math.Sqrt(deltaX * deltaX + deltaY *

deltaY)

 

}

 

 

}

 

 

 

 

Warum ist der Source-Code schlecht?

Beim Feature Envy Code-Smell werden Funktionen die eigentlich zur bereits bestehenden Klasse gehören in eigne neue Klassen ausgelagert. Das führt zu einer Verteilung von Logik und schließlich auch zu einer gestiegenen Komplexität, die das Entwickeln und Testen erschwert und somit zu mehr Fehlern führt. Außerdem führt es zu einer sehr starken Kopplung zwischen der bereits bestehenden Klasse und der neue. Ändert ein Software-Engineer nun etwas in der älteren Klasse, so kann es sein, dass Auswirkungen auf die neuere neidische Klasse nicht berücksichtigt wurden und Fehler entstehen. Des Weiteren sind neidische Klassen und Altklassen meist nicht gut gekapselt oder die Kapselung wird vom Software-Engineer bewusst aufgeweicht um mit der neuen klasse auf benötigte Informationen der alten Klasse zugreifen zu können.

 

Wie wird man den Code-Smell los?

Im Idealfall kann die eifersüchtige Klasse und deren Funktionalität in die bereits bestehende ältere Klasse integriert werden. Sollte die Klasse nicht bearbeitet werden können so ist es ratsam einen Wrapper zu bauen und hier die Funktionalität zu vereinen. Gegebenenfalls können in C# für die Beseitigung des Code-Smells auch Extension-Methods verwendet werden.

 

Wie entsteht der Code-Smell?

Der Code-Smell entsteht, weil Software-Engineers mit Objektorientierung nicht so vertraut sind und prozedural denken. Der Software-Engineer implementiert an der falschen Stelle, wo er eigentlich einen Aufruf machen sollte erweitert er Funktionalität anstatt diese in die richtige Klasse zu verlagern.

 

Wann ist es OK?

Es gibt einige Edge-Cases in denen Feature Envy durchaus Sinn macht und tolerierbar ist, beispielsweise wenn das Verschieben der Funktionalität unerwünschte Abhängigkeiten hervorrufen würde oder wenn bewusst das Strategy-Pattern oder Visitor-Pattern verwendet wurde.

 

Error-Code

 

Beschreibung

Der Error-Code – Code-Smell ist ein Code-Smell der aus älteren prozeduralen Programmiersprachen wie C hervorgeht. Es wird der Rückgabeparameter der Methode verwendet um einen Error-Code auszugaben.

 

Beispiel:

Schlechter Code Guter Code
 

class RouteControl

{

public const int ARGUMENT_IS_NULL_ERROR = 3;

public const int NOT_REACHABLE_ERROR = 7;

 

public int CalcFlightLen(FlightRoute

flight)

{

if(flight == null)

{

return ARGUMENT_IS_NULL_ERROR;

}

 

… //Calculates Flight Length

 

if(flightLength > MAX_FLIGHT_LENGTH)

{

return NOT_REACHABLE_ERROR;

}

 

 

 

}

 

 

class RouteControl

{

public const int ARGUMENT_IS_NULL_ERROR = 3;

public const int NOT_REACHABLE_ERROR = 7;

 

public int CalcFlightLen(FlightRoute

flight)

{

if(flight == null)

{

throw new NullReferenceException(„The provided route  must not be null“);

}

 

… //Calculates Flight Length

 

if(flightLength > MAX_FLIGHT_LENGTH)

{

throw new NotReachableException(„The calculated route  can not be reached“);

}

 

 

 

}

 

 

Warum ist der Source-Code schlecht?

Error-Codes sind Bad-Practice weil sie sehr Fehleranfällig sind. Wird ein Error-Code zurückgegeben muss dieser an Ort und Stelle sofort überprüft werden und ggf. weitergegeben werden. Diese Behandlung kann aber vergessen werden was zu Fehlverhalten der Software führen kann. Der Error-Code muss auch eindeutig sein und kann im schlimmsten Fall mit echten Rückgabewerten kombiniert werden. Zum Beispiel dann, wenn der Software-Engineer entscheidet, dass alle Rückgabewerte die negativ sind Fehlercodes sind, alle die positiv sind jedoch echte Rückgabewerte der Methode sind. Dies macht das Debuggen schwer und komplex.

Das Framework unterstütz auch nicht bei der Behandlung der Error-Codes, sodass der Software-Engineer voll und ganz auf sich allein gestellt ist. Es wird außerdem der Rückgabewert blockiert, der somit nicht mehr verwendet werden kann. Stattdessen muss ein Output-Parameter verwendet werden. Dies wiederum ist ein eigenes Code-Smell mit all seinen negativen Konsequenzen.

Durch die Deklarierung der Error-Codes in der Mutterklasse und die Behandlung beim Aufrufer führt die Verwendung außerdem zu einer starken Kopplung zwischen Aufrufer und Mutterklasse.

 

Wie wird man den Code-Smell los?

Diesen Code-Smell wird man los, indem das vom Framework angebotene Exception-Handling verwendet wird. Die Error-Codes werden durch vorhandene oder neu definierte Exceptions ausgetauscht. Im Aufrufenden Code werden try-catch Blöcke verwendet.

 

Wie entsteht der Code-Smell?

Solch ein Programmierstiel war bei Programmiersprachen wie C oder FORTRAN Good-Practice. Diese prozeduralen Programmiersprachen boten keine andere Möglichkeit als über Rückgabewerte Fehler weiterzugeben. In modernen Programmiersprachen wie beispielsweise C# wurden jedoch Exceptions eingeführt die das Problem integrierter lösen und dem Software-Engineer mehr

 

Wann ist es OK?

Heutzutage gibt es keine Szenarien in C# oder anderen Programmiersprachen, die eine Verwendung von Error-Codes notwendig machen. Es kann aber sein, dass bei Kommunikationsschnittstellen zu Hardware-Systemen diese Error-Codes liefern. In diesen Fällen ist es am sinnvollsten die Error-Codes durch Wrapper mit Exceptions weg zu kapseln.

 


Alle Code-Smells im praktischen eBook: F*ck it smells – Clean Code in C#

Cover ebook v4

[Amazon 2,99€]


Weitere Blogs zur Digitalisierungsstrategie

Code-Smells: Dispensables

Code-Smells: Bloaters

Code 10 Bloaters

Weitere Buchempfehlungen

[Links zu Amazon]

Cover New V1
[Amazon 9,99€] [Amazon 34,99 €] [Amazon 24,95 €]
[Amazon 34,00 €] [Amazon 25,99 €] [Amazon 42,00 €]

Zum Autor:

David Theil ist DigitalisierungsCoach und hilft Unternhemen bei der Softwareentwicklung, App-Entwicklung und bei der Digitalisierung und Digitalisierungsprojekten

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

https://medium.com/@david.theil

https://twitter.com/DavidTheil

 

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden /  Ändern )

Google Foto

Du kommentierst mit Deinem Google-Konto. Abmelden /  Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden /  Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden /  Ändern )

Verbinde mit %s

Create a website or blog at WordPress.com

Nach oben ↑

%d Bloggern gefällt das: