* docs: reformulate text, add links to further languages and paragraph about the book in central README.md (#2275) * docs: shorten text for link to payhip (#2275) * docs: reformulate german translation for Abstract Document (#2275) * Create folder for Abstract Factory * Create README.md for Abstract Document * Translate README.md for Abstract Document to German * correct typo * docs: add class diagrams for all patterns (#2275) * docs: add missing words in abstract-factory.README.md (#2275) * docs: Create German README.md for Active Object #2275 first text part * docs: finish German translation of README.md for Active Object * docs: translate actor-model into German #2295 * docs: add German translation for Acyclic Visitor #2295 * correct typo * docs: Translate Singleton into German #2295 * docs: Translate Prototype into German #2295 * Delete localization/de/Abstract Factory * insert line break * correct typos in actor-model * realignment of java code block * docs: translate Adapter Pattern into German #2295 * Update README.md change 'lizenz' to 'Lizenz' in badge * Update README.md translate 'benefits' and 'trade-offs' * remove additional bullet point after line break * correct indentation * docs: translate Dependency Injection into German #2295 * docs: translate Bridge into German #2295 * correct typos * docs: Translate Builder into German * delete english text * little changes in formulation * Update README.md change link to image * docs: remove spanish files (#2275) * docs: remove non-translated patterns (#2275) * Create README.md docs: Translate Step Builder into German #2275 * Create README.md docs: Translate Fluent Interface into German #2275 * eager is eifrig, not gierig * Translate Chain of Responsibility into German #2275
6.4 KiB
shortTitle, category, language, tag
| shortTitle | category | language | tag | ||||||
|---|---|---|---|---|---|---|---|---|---|
| Adapter | Structural | de |
|
Alternativbezeichnung
- Wrapper
Zweck
Das Adapter-Pattern konvertiert die Schnittstelle einer Klasse in eine andere Schnittstelle, die zu den Bedürfnissen der Anwender passt, und sorgt so für Kompatibilität.
Detaillierte Erklärung
Vergleich mit der analogen Welt
Stellen Sie sich vor, Sie haben einige Bilder auf Ihrer Speicherkarte und wollen diese auf Ihren Computer übertragen. Dafür brauchen Sie einen Kartenleser, der mit den Anschlüssen des Rechners kompatibel ist, sodass dieser auf die Daten auf der Karten zugreifen kann. Dieser Kartenleser ist ein Beispiel für einen Adapter. Ein anderes Beispiel sind die Adapter, mit denen man deutsche Netzstecker in ausländischen Steckdosen verwenden kann, in die sie sonst nicht passen würden. Auch ein Übersetzer, der die Worte eines Sprechers in die Sprache des ausländischen Publikums übersetzt, erfüllt die Funktion eines Adapters.
In einfachen Worten
Das Adapter-Pattern verpackt ein normalerweise inkompatibles Objekt so, dass es mit einer anderen Klasse kompatibel wird.
Wikipedia sagt
Das Adapter-Pattern in der Softwareentwicklung ist ein Entwurfsmuster, das die Schnittstelle einer bestehenden Klasse im Rahmen einer neuen Schnittstelle nutzbar macht. Es wird oft verwendet, damit Klassen zusammenarbeiten können, ohne ihren Quellcode zu verändern.
Ablaufdiagramm
Programmbeispiel
Betrachten wir einen Möchtegern-Kapität, der zwar rudern kann, aber noch nie gesegelt ist.
Wir beginnen mit dem Interface RowingBoat und der Klasse FishingBoat
public interface RowingBoat {
void row();
}
public class FishingBoat {
public void sail() {
LOGGER.info("The fishing boat is sailing");
}
}
Der Kapität erwartet, dass sich ein Schiff mit der row-Methode von RowingBoat steuern lässt.
public class Captain {
private final RowingBoat rowingBoat;
public Captain(RowingBoat rowingBoat) {
this.rowingBoat = rowingBoat;
}
public void row() {
rowingBoat.row();
}
}
Nun kommen Piraten und unser Kapitän muss fliehen, hat aber nur ein Fischerboot zur Verfügung. Wir brauchen einen Adapter, mit dem er auch dieses Boot durch Rudern steuern kann.
public class FishingBoatAdapter implements RowingBoat {
private final FishingBoat boat;
public FishingBoatAdapter() {
boat = new FishingBoat();
}
@Override
public void row() {
boat.sail();
}
}
Nun segelt das FishingBoat, indem der Kapitän rudert, und er kann fliehen.
public static void main(final String[] args) {
// The captain can only operate rowing boats but with adapter he is able to
// use fishing boats as well
var captain = new Captain(new FishingBoatAdapter());
captain.row();
}
Programmausgabe:
10:25:08.074 [main] INFO com.iluwatar.adapter.FishingBoat -- The fishing boat is sailing
Verwendung
Das Adapter-Pattern ist geeignet für diese Fälle
- Sie wollen eine bestehende Klasse benutzen, deren Schnittstelle anders als benötigt ist.
- Sie wollen eine wiederverwendbare Klasse schreiben, die auch mit fremden Klassen zusammen arbeiten kann, die nicht unbedingt kompatible Schnittstellen haben.
- Sie müssen verschiedene Tochterklassen verwenden, bei denen es zu aufwendig wäre, zu jeder einzelnen eine Subklasse mit angepasster Schnittstelle zu erstellen. Ein Adapter kann die Schnittstelle der Elternklasse bedarfsgerecht anpassen.
- Die meisten Anwendungen, die Fremdbibliotheken verwenden, nutzen einen Adapter für die Fremdklassen, um die eigenen Anwendung vom fremden zu entkoppeln.
Tutorials
- Using the Adapter Design Pattern in Java (Dzone)
- Adapter in Java (Refactoring Guru)
- The Adapter Pattern in Java (Baeldung)
- Adapter Design Pattern (GeeksForGeeks)
Vor- und Nachteile
Die Vor- und Nachteile hängen davon ab, ob ein Klassen- oder ein Objektadapter implementiert wird.
Ein Klassenadapter adaptiert durch Bindung an eine spezifische zu adaptierende Klasse. Er kann das Verhalten der zu adaptierenden Klasse überschreiben, weil er als deren Tochterklasse implementiert wird. Das hat allerdings zur Folge, dass mit einer Klasse nicht auch all ihre Subklassen adaptiert werden können. Bei diesem Adaptertyp wird lediglich ein neues Objekt eingeführt, ohne dass mit einem extra Zeiger der Zugriff darauf ermöglicht werden muss.
Ein Objektadapter hingegen kann mit verschiedenen zu adaptierenden Klassen arbeiten, auch mit allen Subklassen. Er kann allen adaptierten Klassen zugleich Funktionalität hinzufügen. Allerdings wird es damit schwerer, das Verhalten zu überschreiben, weil man dafür eine Subklasse der adaptierten Klasse benötigt und der Adapter sich auf diese Subklasse statt auf die ursprünglich adaptierte Klasse beziehen muss.
Reale Java-Anwendungen
java.io.InputStreamReaderandjava.io.OutputStreamWriterin der Java-IO-Bibliothek.- GUI-Komponentenbibliotheken, die per Plugin oder Adapter zwischen verschiedenen Kompontentenschnittstellen konvertieren können.
- java.util.Arrays#asList()
- java.util.Collections#list()
- java.util.Collections#enumeration()
- javax.xml.bind.annotation.adapters.XMLAdapter
