Adapter (Entwurfsmuster)
Der Adapter (englisch adapter pattern) – auch die Hüllenklasse[1] oder der Wrapper (von englisch wrapper ‚Verpackung‘, ‚Umschlag‘) genannt – ist ein Entwurfsmuster aus dem Bereich der Softwareentwicklung, das zur Kategorie der Strukturmuster (engl. structural patterns) gehört. Das Muster dient zur Übersetzung einer Schnittstelle in eine andere. Dadurch wird die Kommunikation von Klassen mit zueinander inkompatiblen Schnittstellen ermöglicht.[2] Es ist ein Entwurfsmuster der sogenannten GoF-Muster (Gang of Four, siehe Viererbande).
1 Verwendung
2 UML-Diagramm
2.1 Adapter mit Delegation (Objektadapter)
2.1.1 Hüllenklassen für primitive Datentypen
2.1.2 Hüllenklassen für prozedurale Bibliotheken
2.2 Adapter mit Vererbung (Klassenadapter) 4 Akteure
5 Beispiele
5.1 Allgemein
5.2 Klassenadapter
5.2.1 Konkretes Beispiel in C++
6 Verwandte Entwurfsmuster
Verwendung[Bearbeiten]
Der Adapter findet Anwendung, wenn eine existierende Klasse verwendet werden soll, deren Schnittstelle nicht der benötigten Schnittstelle entspricht. Dies tritt insbesondere dann auf, wenn Klassen, die zur Wiederverwendung konzipiert wurden – wie Werkzeugsammlungen oder Klassenbibliotheken – verwendet werden sollen. Diese stellen ihre Dienste durch klar definierte Schnittstellen zur Verfügung, die in der Regel nicht geändert werden sollen und häufig auch nicht geändert werden können, da sie von Dritten stammen. Des Weiteren wird der Adapter bei der Erstellung wiederverwendbarer Klassen benutzt, wenn diese mit unabhängigen oder nichtvorhersehbaren Klassen zusammenarbeiten sollen.
Die sogenannte „Gang of Four“ (Viererbande) beschreibt zwei Realisierungsalternativen. Die erste ist der Adapter mit Delegation (der sogenannte Objektadapter), die zweite der Adapter mit Vererbung (Klassenadapter).
Adapter mit Delegation (Objektadapter)[Bearbeiten]
Hierbei hat der Adapter eine Assoziation zu der zu adaptierenden Klasse und leitet die Anfragen per Delegation weiter.
Der Vorteil ist, dass der Adapter und der dahinterliegende Dienst ausgetauscht werden können; dafür muss die gesamte genutzte Schnittstelle implementiert werden, auch wenn nur ein Teil der Implementierung angepasst werden soll.
Objektadapter sind auch als Hüllenklasse oder Wrapper-Klasse bekannt. Dabei können nicht nur andere Klassen gekapselt werden, sondern auch primitive Datentypen oder prozedurale Programmierbibliotheken.
Hüllenklassen für primitive Datentypen[Bearbeiten]
Eine Anwendung für Hüllenklassen in objektorientierten Programmiersprachen ist, Klassen für Grunddatentypen zur Verfügung zu stellen, um die Handhabung zu vereinfachen und zusätzliche Funktionen zur Verfügung zu stellen. So gibt es z. B. in der Programmiersprache Java für den Typ int die Klasse Integer , für char die Klasse Character oder für float die Klasse Float (entsprechend auch Short , Long , Boolean und Double ). Diese Hüllenklassen ermöglichen den objektorientierten Umgang mit primitiven Datentypen, zum Beispiel, um sie in ein Reflexionskonzept einzubinden.
Um die Verwendung von Hüllenklassen zu vereinfachen, wurde in Java 5 das so genannte Autoboxing oder Boxing eingeführt. Diese Technik ermöglicht die Verwendung von Hüllenklassen in der von primitiven Datentypen gewohnten Form. Statt der Objekterzeugung mittels Integer i = new Integer(100) kann einfach die Schreibweise Integer i = 100 genutzt werden. Ebenfalls kann die Referenzvariable i genutzt werden, als wäre sie eine gewöhnliche int-Variable.[3] Die einfache Schreibweise und bessere Lesbarkeit gehen auf Kosten einer erheblich schlechteren Ausführungsgeschwindigkeit.
Hüllenklassen für prozedurale Bibliotheken[Bearbeiten]
Eine weitere wichtige Anwendung ist die Anpassung einer prozeduralen Bibliothek an ein objektorientiertes Softwaresystem. Hierbei werden die funktionsorientierten Dienste der Bibliothek in ein oder mehrere Objekte gekapselt. Diese Anwendungsform ist häufig als Entwurfsmuster Fassade zu finden.
Adapter mit Vererbung (Klassenadapter)[Bearbeiten]
Ein Klassenadapter wird mit Hilfe von Mehrfachvererbung realisiert. Zum einen erbt er die Implementierung der zu adaptierenden Klasse. Zum anderen die zu implementierende Schnittstelle. Der Aufruf erfolgt dann durch Selbstdelegation.