Zum Inhalt springen
L

Wikipedia · einfach zusammengefasst · Stand

Adapter (Entwurfsmuster)

Der Adapter (englisch adapter pattern) – auch die Hüllenklasse oder der Wrapper (v. engl. wrapper ‚Verpackung', ‚Umschlag') genannt – ist ein Entwurfsmuster …

Inhalt5 Abschnitte
  1. 1. Zweck und Einsatz
  2. 2. Aufbau und Beteiligte
  3. 3. Objektadapter und Hüllenklassen
  4. 4. Klassenadapter sowie Vor- und Nachteile
  5. 5. Beispiele und Abgrenzung

Zweck und Einsatz

Der Adapter, auch Hüllenklasse oder Wrapper genannt, ist ein Strukturmuster der GoF-Entwurfsmuster. Er übersetzt eine Schnittstelle in eine andere und ermöglicht dadurch die Zusammenarbeit von Klassen mit inkompatiblen Schnittstellen.

Er wird eingesetzt, wenn eine vorhandene Klasse genutzt werden soll, ihre Schnittstelle aber nicht zur benötigten Schnittstelle passt. Das ist besonders bei fremden oder wiederverwendbaren Werkzeugsammlungen und Klassenbibliotheken wichtig: Deren festgelegte Schnittstellen sollen oder können meist nicht geändert werden. Außerdem hilft ein Adapter bei wiederverwendbaren Klassen, die mit unabhängigen oder nicht vorhersehbaren Klassen zusammenarbeiten müssen.

Aufbau und Beteiligte

Der Dienst stellt wiederverwendbare Leistungen über seine feste Schnittstelle bereit. Der Klient möchte diese Leistungen nutzen, erwartet aber eine andere, inkompatible Schnittstelle. Das Ziel legt die Schnittstelle fest, die der Klient verwenden kann. Der Adapter vermittelt zwischen beiden, indem er die Dienstschnittstelle auf die vom Klienten benötigte Schnittstelle abbildet.

Die GoF beschreibt dafür zwei Varianten: den Objektadapter mit Delegation und den Klassenadapter mit Vererbung.

Objektadapter und Hüllenklassen

Ein Objektadapter besitzt eine Assoziation zu dem anzupassenden Objekt. Er nimmt Anfragen über die Ziel-Schnittstelle entgegen und leitet sie durch Delegation an den Dienst weiter. Delegation bedeutet hier: Der Adapter übergibt die Arbeit an ein enthaltenes oder verbundenes Objekt.

Ein Vorteil ist, dass sowohl Adapter als auch der dahinterliegende Dienst ausgetauscht werden können. Allerdings muss der Adapter die gesamte verwendete Schnittstelle implementieren, auch wenn nur ein Teil angepasst werden soll. Objektadapter heißen auch Hüllenklassen oder Wrapper-Klassen.

Hüllenklassen können primitive Datentypen objektorientiert nutzbar machen. Java bietet etwa Integer für int, Character für char und Float für float sowie Byte, Short, Long, Boolean und Double. Damit können primitive Werte beispielsweise in ein Reflexionskonzept eingebunden werden. Seit Java 5 erlaubt Autoboxing beziehungsweise Boxing die Schreibweise Integer i = 100 statt Integer i = new Integer(100); auch i kann ähnlich wie eine int-Variable verwendet werden. Die bessere Lesbarkeit und einfache Schreibweise gehen jedoch mit erheblich schlechterer Ausführungsgeschwindigkeit einher.

Auch prozedurale Bibliotheken lassen sich an objektorientierte Systeme anpassen, indem ihre funktionsorientierten Dienste in ein oder mehrere Objekte gekapselt werden. Diese Anwendung erscheint häufig als Entwurfsmuster Fassade.

Klassenadapter sowie Vor- und Nachteile

Ein Klassenadapter wird durch Mehrfachvererbung umgesetzt: Er erbt einerseits die Implementierung der anzupassenden Klasse und andererseits die zu implementierende Schnittstelle. Der Aufruf erfolgt durch Selbstdelegation.

Diese Variante ist sinnvoll, wenn die Sprache die nötigen Eigenschaften wie Mehrfachvererbung und private Vererbung besitzt, beispielsweise C++. Sprachen ohne private und Mehrfachvererbung sind dafür eher ungeeignet. Eine Kombination aus Klassenvererbung und Interface-Implementierung kann zwar als Adapter dienen, stellt aber keinen GoF-Adapter im engeren Sinn dar, wenn die Adapterklasse ihren Klienten alle Methoden bereitstellt statt eine Schnittstelle in eine andere zu überführen.

Ein Klassenadapter passt sich genau einer Zielklasse an und kann deshalb nur deren Verhalten überschreiben. Ein Objektadapter kann dagegen auch Unterklassen anpassen. Dafür kann ein Klassenadapter Unterklassen nicht automatisch mit anpassen.

Beispiele und Abgrenzung

Bei grafischen Benutzeroberflächen können Objektadapter den Zugriff auf das Modell steuern. Eine Checkbox kann dadurch sowohl einen gepufferten Boolean-Wert als auch unmittelbar das Ergebnis einer Bedingung anzeigen. Visualworks Smalltalk nutzt dieses Muster intensiv.

Ein C++-Beispiel verbindet eine Bibliothek für algorithmische Geometrie mit einer GUI-Bibliothek. Die Geometrie-Bibliothek erwartet einen abstrakten Kreis mit getRadius() und getMittelpunkt(); ihre Funktion schneidetKreisKreis berechnet den Abstand der Mittelpunkte und prüft: abstandDerKreise <= (k1.getRadius() + k2.getRadius()). Die GUI-Bibliothek besitzt dagegen Circle mit getX(), getY() und getR(). CircleAdapter implementiert Kreis und passt einen Circle an: getRadius() liefert getR(), getMittelpunkt() liefert Punkt(getX(), getY()). So können zwei GUI-Circle-Objekte vom Geometriealgorithmus auf Schnitt getestet werden, ohne eine der Bibliotheken zu ändern.

Brücke und Adapter sind ähnlich, unterscheiden sich aber im Zweck: Die Brücke trennt Schnittstelle und Implementierung bewusst beim Entwurf; ein Adapter passt eine Schnittstelle nachträglich an eine andere an. Fassade und Adapter sind beide Hüllenklassen. Eine Fassade verbirgt den Funktionsumfang einer Bibliothek ganz oder teilweise, während ein Adapter nur deren Schnittstelle verändert.

Weiterlesen