Ein Angebot von

Anti-Patterns: Wiederkehrende Entwicklerfehler erkennen und vermeiden

| Autor / Redakteur: Stephan Roth* / Martina Hafner

Sogenannte Muster, auch Patterns oder Idioms genannt, sollen dem Entwickler beim Erstellen einer soliden Software-Architektur helfen, anhand derer er seinen Code aufziehen kann. Gleichwohl lohnt es sich, auch über sogenannte Anti-Patterns Bescheid zu wissen – Muster, anhand derer sich wiederholt auftretende Entwicklungsfehler erkennen lassen.
Sogenannte Muster, auch Patterns oder Idioms genannt, sollen dem Entwickler beim Erstellen einer soliden Software-Architektur helfen, anhand derer er seinen Code aufziehen kann. Gleichwohl lohnt es sich, auch über sogenannte Anti-Patterns Bescheid zu wissen – Muster, anhand derer sich wiederholt auftretende Entwicklungsfehler erkennen lassen. (Bild: gemeinfrei / Pixabay)

Entwurfsmuster (Design Pattern) sind vor allem in der objekt-orientierten Softwareentwicklung als bewährte Lösungen für immer wiederkehrende Entwurfsprobleme weitestgehend bekannt und verbreitet. Wer aber seinem Software-Entwicklungsprojekt gezielt Schaden zufügen möchte, der bedient sich lieber aus dem reichhaltigen Repertoire der Anti-Pattern.

Als die sogenannte „Gang Of Four“ (namentlich: Erich Gamma, Richard Helm, Ralph Johnson und John Vlissides) im Jahr 1994 ihr legendäres Entwurfsmuster-Buch [1] veröffentlichten, wurden Design Pattern zu einem wichtigen Bestandteil im Werkzeugkasten vieler Softwareentwickler. In den darauf folgenden Jahren erschienen immer mehr Mustersammlungen für unterschiedlichste Anwendungszwecke in der Softwareentwicklung, wie beispielsweise Bücher zu Softwarearchitekturmustern, Muster für die Anforderungs- und Geschäftsprozessanalyse, sowie auch technologienahe Muster, die sogenannten Idioms.

Das Buch der Gang Of Four wurde seit dessen Erstveröffentlichung nie überarbeitet. Auch heute, 20 Jahre später, ist immer noch die erste Auflage erhältlich. Als Erich Gamma im Jahr 2009 in einem Interview für InformIT [2] gefragt wurde, was er denn ändern würde, wenn er das Buch „refaktorisieren“ müsste, hat er geantwortet (Auszug):

Erich: (…) We have found that the object-oriented design principles and most of the patterns haven't changed since then. We wanted to change the categorization, add some new members and also drop some of the patterns. Most of the discussion was about changing the categorization and in particular which patterns to drop.

When discussing which patterns to drop, we found that we still love them all. (Not really - I'm in favor of dropping Singleton. Its use is almost always a design smell.) (…)

In diesem Interview wurden die Autoren von Larry O’Brien auch zu Anti-Pattern befragt:

Larry:After the pattern bandwagon, there was a trend towards "anti-patterns." Are anti-patterns as valuable as patterns?

Richard:Probably - they provide a way to share and learn from mistakes.

Ralph: I prefer the notion of "code smells," or "design smells"/"architecture smells" etc. They aren't always mistakes. (…)

Ganz gleich welchen der zuletzt genannten Begriffe man bevorzugt: offensichtlich haben auch Gamma et al. erkannt, dass neben den Entwurfsmustern auch die Beschreibung von, und das Wissen über, schlechte Lösungsansätze für die interne Softwarequalität nutzbringend sein kann. Mit Hilfe von Anti-Pattern können wiederkehrende Fehler bei der Softwareentwicklung, identifiziert und in generalisierter Form dokumentiert werden. Durch die Kenntnis von Anti-Pattern können die Sinne der Entwickler für problematische Lösungen geschärft werden, um solche Fehler von vornherein zu vermeiden.

Im Folgenden werde ich lediglich eine kleine Auswahl derjenigen Anti-Patterns erläutern, die im Konferenzvortrag präsentiert werden.

Das Gottobjekt, oder: Die Angst vor Klassen

“The first rule of classes is that they should be small. The second rule of classes is that they should be smaller than that.” (Robert C. Martin, Clean Code)

Das Gottobjekt.
Das Gottobjekt. (Bild: oose)

Unter einem Gottobjekt (auch: Gottklasse, Blob) versteht man in objektorientierten Sprachen eine sehr große Klasse mit vielen Verantwortlichkeiten. Solche Klassen sind zumeist wie ein riesiger Gemischtwarenladen. Verschiedene fachliche Aspekte des Softwaresystems sind in einer solchen Klasse vereint und zumeist auch ungünstig miteinander verwoben. Man spricht in diesem Zusammenhang auch von schwacher Kohäsion.

Ein Gottobjekt ist in vielerlei Hinsicht problematisch. Da eine solche Klasse auch eine Vielzahl von Funktionen an ihrer öffentlichen Schnittstelle anbietet. machen sich zumeist viele andere Softwareeinheiten von ihr abhängig (siehe Bild). Die Testbarkeit und Evolvierbarkeit sinkt damit rapide, und eine Wiederverwendung in einem anderen System wird nahezu unmöglich. Große Klassen sind in der Regel sehr komplex und somit von Entwicklern viel schwieriger zu verstehen als kleine, überschaubare Einheiten. Mitunter fällt es schon schwer, einen präzisen und aussagekräftigen Namen für solche Klassen zu finden. Sie heißen daher oft „…Manager“.

Eine Ursache für das Entstehen solcher Gottobjekte ist häufig eine Art „Angst vor Klassen“. Viele Entwickler schrecken davor zurück viele kleine Klassen zu schreiben. Stattdessen verwenden sie das Sprachmittel der Klasse eher als einen Namensraum für ein eigentlich prozedurales Programm und versuchen alles irgendwie in bestehende Klassen unterzubringen. Manchmal fehlen auch Kenntnisse über objekt-orientierte Paradigmen. In objekt-orientierten Programmiersprachen ist die Klasse aber ein völlig normales Sprachelement, wie eine Funktion oder Variable auch.

Um das Anti-Pattern Gottobjekt zu vermeiden, sollten folgende Prinzipien beachtet bzw. können folgende Praktiken angewandt werden:

Single Responsibility Principle (SRP): Jede Softwareeinheit sollte nur exakt eine klar definierte Verantwortlichkeit haben

• Beachte starke Kohäsion (starker fachlicher Zusammenhalt)

• Die Metrik der Lines of Code (LOC) pro Klasse kann ein hilfreicher Indikator sein: hat eine Klasse mehr als etwa 100 Zeilen Code, so sollte man sie hinsichtlich SRP untersuchen.

Divide et Impera (Teile und Herrsche): Klassen, die Services/Funktionalitäten auf einem hohen Abstraktionsniveau anbieten, sollten sich aus Klassen zusammensetzen, die Teilfunktionalitäten auf dem nächst niedrigeren Abstraktionsniveau realisieren.

• Praktiziere Testgetriebene Entwicklung (Test-Driven Development, TDD) als unterstützende Methode für das saubere Entwerfen von Softwareeinheiten.

Copy & Paste Programmierung (Code-Duplizierung)

Dass das Kopieren von Sourcecode, um den kopierten Code an anderer Stelle einzufügen und zu verwenden, erhebliche Probleme verursachen kann, liegt auf der Hand. Dennoch wird es immer noch häufig praktiziert, zumeist aus Bequemlichkeit, weil es gerade schnell gehen muss, oder weil unerfahrene Programmierer überfordert sind elegantere und redundanzfreie Lösungen zu entwickeln.

Dabei handelt es sich um eine schwerwiegende Verletzung des DRY-Prinzips (Don’t repeat yourself!), welches in dem Buch The Pragmatic Programmer [3] beschrieben wird. Das DRY-Prinzip besagt, dass jedes Stück Wissen in einem System nur exakt eine einzige und maßgebliche Repräsentation haben darf.

Sourcecode-Kommentare

„Don’t comment bad code – rewrite it!“ (Brian W. Kernighan, P. J. Plaugher)

Bezüglich Kommentierungen im Quelltext scheint in vielen Projekten die Prämisse zu gelten „Viel hilft viel“ – doch das genaue Gegenteil ist der Fall! Kommentare sind, von wenigen Ausnahmen abgesehen, ein code smell und sollten weitestgehend vermieden werden.

Softwareentwickler sollen mit ihrem Code Geschichten erzählen. Die heutzutage verwendeten Programmiersprachen sind derart ausdrucksstark, dass sich damit problemlos selbsterklärender Code schreiben lässt, der von Entwicklern schnell gelesen und verstanden werden kann. Durch den Einsatz von guten und aussagekräftigen Namen für Klassen, Funktionen und Variablen, sowie einem guten Programmierstil, kann man sehr gut leicht verständlichen Code schreiben.

Zusätzliche Kommentare erzeugen lediglich Rauschen und tendieren zudem schnell dazu, entweder das DRY-Prinzip zu verletzen (redundante Informationen, s.o.), oder, was besonders gefährlich ist, zu veralten und somit Sachverhalte falsch wiederzugeben. Kommentare sind heutzutage nur dann erforderlich, wenn ein ganz außergewöhnlicher, zumeist fachlicher Sachverhalt betont werden muss, der sich nicht so ohne Weiteres aus dem Code erschließt.

Wann immer Sie also bei der Entwicklung das Verlangen verspüren, einen Kommentar schreiben zu müssen, sollten Sie stattdessen überlegen wie Sie den betroffenen Codeabschnitt verbessern können so dass der Kommentar überflüssig wird.

Singleton

Wie Erich Gamma in dem oben teilweise zitierten Interview ja schon angedeutet hat, würde er das Erzeugungsmuster Singleton gerne aus seinem Buch entfernen. Das hat gute Gründe, denn mittlerweile wird dieses Entwurfsmuster eher als Anti-Pattern gesehen.

Das eigentliche Ziel dieses Entwurfsmusters war es zu gewährleisten, dass nur eine einzige Instanz von einer Klasse im gesamten, laufenden Programm existiert. An dieser Stelle sollte schon mal die berechtigte Frage geklärt werden: Wozu? Welches Entwurfsproblem wird damit gelöst? Welche Anforderung liegt einem Einsatz dieses Musters zu Grunde? Häufig wird man feststellen: Eine fachliche Motivation gibt es dafür zumeist nicht.

Ein Singleton verhält sich wie eine globale Variable. Durch seine globale Sichtbarkeit machen sich zumeist viele Klassen von dem Singleton abhängig (Damit tendieren Singletons auch potenziell zu Gottobjekten zu werden). Doch diese Abhängigkeiten sind so gut wie nie offensichtlich: Ob ein Singleton von einer Klasse verwendet wird, erschließt sich in der Regel nicht aus ihrem Interface, sondern kann nur durch einen Blick in die Implementierung geklärt werden. Singletons erschweren das Unit-Testing erheblich, weil sie einen globalen Zustand einführen, und auch nur schwer durch sog. Test Doubles (auch: Mocks) ersetzbar sind.

In nebenläufigen oder gar verteilten Systemen ist es zudem nicht nur diffizil sicherzustellen, dass wirklich nur eine Instanz existiert. In solchen Systemen können zudem Singletons zu subtilen und nur mühsam zu findenden Fehlern führen, beispielsweise wenn mehrere Threads konkurrierend auf das Singleton zugreifen.

Daher sollte man Singletons vermeiden, und sie sind in der Regel auch entbehrlich. Die Lösung heißt Dependency Injection (DI): Erzeuge lediglich eine Instanz, und „injiziere“ diese mittels eines parametrisierten Konstruktors, oder mit Hilfe einer set-Methode, in die Klassen, die sie verwenden. Durch DI wird die Abhängigkeit der Verwender zu dieser Klasse in der Schnittstelle der Verwender sichtbar.

Software Design Patterns

Software Design Patterns

16.10.18 - Viele Entwickler besitzen einen Vorrat an allgemein anwendbaren Entwurfsmustern, mit deren Hilfe flexible, leicht anpassbare und gut wartbare Applikationen entwickelt werden können. Aber der Versuch, diese Software Design Patterns in der Praxis anzuwenden, stellt sich oft schwieriger heraus als erwartet. Dies kann viele Ursachen haben. lesen

Quellenverzeichnis

[1] Erich Gamma, Richard Helm, Ralph Johnson und John Vlissides: Design Patterns. Elements of Reusable Object-Oriented Software. Addison-Wesley, 1995
[2] Design Patterns 15 Years Later: An Interview with Erich Gamma, Richard Helm, and Ralph Johnson, zuletzt eingesehen am 29.07.2019.
[3] Andrew Hunt und David Thomas: The Pragmatic Programmer. From Journeyman To Master. Addison-Wesley, 1999

Dieser Beitrag stammt aus dem Tagungsband des Embedded Software Engineering Kongress 2014.

* Stephan Roth ist Trainer und Berater bei der oose Innovative Informatik eG in Hamburg. Mit freundlicher Genehmigung wurde dieser Beitrag dem Tagungsband Embedded Software Engineering Kongress 2014 entnommen.

Kommentar zu diesem Artikel abgeben

Schreiben Sie uns hier Ihre Meinung ...
(nicht registrierter User)

Zur Wahrung unserer Interessen speichern wir zusätzlich zu den o.g. Informationen die IP-Adresse. Dies dient ausschließlich dem Zweck, dass Sie als Urheber des Kommentars identifiziert werden können. Rechtliche Grundlage ist die Wahrung berechtigter Interessen gem. Art 6 Abs 1 lit. f) DSGVO.
Kommentar abschicken
copyright

Dieser Beitrag ist urheberrechtlich geschützt. Sie wollen ihn für Ihre Zwecke verwenden? Infos finden Sie unter www.mycontentfactory.de (ID: 43691228 / Entwurf)