Diskussion:Adapter (Entwurfsmuster)
Vorteile und Nachteile
BearbeitenIch habe mal Vorteile und Nachteile rausgeschmissen. Grund: Hier wird von Klassen- und Objektadaptern gesprochen, das sind aber Begriffe, die im gesamten Artikel nicht vorkommen, nicht erklärt sind und mir auch nicht bekannt sind. Soweit ich weiß, sind sie auch der "Gang of Four" nicht bekannt.
Außerdem erscheint es mir seltsam, bei Entwurfsmustern von Vor- und Nachteilen zu sprechen; entweder passen sie auf den Anwendungsfall, oder sie passen nicht. Das alleine wäre aber kein Grund, sie zu löschen.
Außerdem ist die Aussage, ein Objektadapter müsse Unterklassen bilden, falsch.
Der Originaltext war:
==Vorteile==
- Ein Klassenadapter passt genau eine Zielklasse an.
- Ein Klassenadapter kann dadurch das Verhalten der Zielklasse überschreiben.
- Ein Objektadapter kann auch Unterklassen mitanpassen.
==Nachteile==
- Ein Klassenadapter kann nicht zur automatischen Anpassung von Unterklassen verwendet werden.
- Ein Objektadapter muss Unterklassen bilden, um das Verhalten der Zielklasse zu überschreiben.
- Klassenadapter lassen sich nur realisieren, wenn die Programmiersprache Schnittstellen oder Mehrfachvererbung unterstützt.
Leider mußte ich auch das Bild zu Adapter mit Vererbung raussschmeißen, da es völlig identisch mit dem von Adapter per Delegation war. War anscheinend ein Versehen. Hat noch jemand das passende Diagramm?--Kuli 11:01, 7. Mär 2005 (CET)
Nachtrag: Wenn die Vor- und Nachteile von der Semantik her an den Artikel angepaßt werden (oder umgekehrt), dann spricht natürlich nichts dagegen, sie wieder reinzunehmen.--Kuli 11:21, 7. Mär 2005 (CET)
- Klassenadapter kenne ich als Begriff für Adapter mit Vererbung, Objektadapter als Adapter mit Assoziation. Müsste dann oben ergänzt werden.
- Bilder hab ich für beide, dann sollte ich aber wohl das andere Bild auch ersetzen, um konsistent zu sein.auch die Möglichkeit bieten, sich besuchen zu lassen und entsprechende Funktionen bereit stellen.
- Zu Vor- und Nachteilen: Die GoF nennt selbst Vor- und Nachteile als Elemente von Beschreibungen von Mustern, siehe Entwurfsmuster. Das ist auch in den meisten Entwurfsmustern mittlerweile integriert, ich finde das auch sehr sinnvoll. Es sind halt Vor- und Nachteile, die man sich durch die Verwendung einhandelt. Im Sinne: Was kann ich damit gut machen, was geht dann nicht mehr so gut.
- Zu Unterklassenbildung bei Objektadaptern: Missverständlich oder zu allgemein ausgedrückt. Wenn man das Verhalten unterklassenspezifisch überschreiben will, muss man Unterklassen bilden. Oder? grübel ...
- Meine Vorschläge: Ich bau die Bilder ein und die Bezeichungen für Klassen- und Objektadapter, Du die gelöschten Vor- und Nachteile bis auf das mit der Unterklassenbildung bei Objektadaptern.
--guwac 12:20, 7. Mär 2005 (CET)
- Nachtrag: Die Bilder waren verschieden. Eines zeigt Assoziation, das andere Vererbung. Die Pfeile sind verschieden. Dann können auch die bereits hochgeladenen Bilder bleiben. -- guwac 12:23, 7. Mär 2005 (CET)
- Noch ein Nachtrag: Objektadapter und Klassenadapter werden sehr wohl als alternative Bezeichnungen erwähnt. Also ich schlag vor, bis auf Deine Erweiterungen stellst Du den rest wieder rein. --guwac 12:25, 7. Mär 2005 (CET)
- So, hab das jetzt schnell selbst wieder in Ordnung gebracht. Wenn Dich die Begriffe in den Vor- und Nachteilen weiterhin stören sollte, kannst du sie ja einfach durch Adapter mit Vererbung und Adapter mit Assoziation ersetzen. Klassenadapter und Objektadapter werden aber in der Liste vor den Bildern als Begriffe zugeordnet und existieren auch in Sekundärliteratur. Die Bilder sind wie gesagt verschieden und stellen den Sachverhalt korrekt dar, weshalb ich das Hochladen meiner eigenen Bilder für überflüssig finde. Und was jetzt kommt bitte nicht böse nehmen: Das nächste Mal genauer lesen bzw. Bilder angucken ;o) --guwac 12:58, 7. Mär 2005 (CET)
- Natürlich bin ich nicht böse! :-) Ich muß auch zugeben, daß ich mich bei den Bildern wohl wirklich verguckt habe. Nächstes mal mache ich die Augen weiter auf!
- Ich habe die Bezeichnungen mal in die Überschriften mit reingenommen. Daß ich den Zusammenhang nicht sehe, liegt auch daran, daß ich die Vor- und Nachteile nicht nachvollziehen kann:
- * Ein Klassenadapter passt genau eine Zielklasse an. -- Was ist daran ein Vorteil???
- * Ein Klassenadapter kann dadurch das Verhalten der Zielklasse überschreiben. -- Eigentlich soll ja ein Adapter die Schnittstelle ändern, nicht das Verhalten. Wenn er das Verhalten ändert, ist er kein Adapter mehr. Okay, man kann es vielleicht so sehen: Vorteil ist, wenn man ohnehin einen Klassenadapter hat, dann kann der praktischerweise auch noch das Verhalten ändern. Sehe ich aber nicht als besonderen Vorteil an.
- * Ein Objektadapter kann auch Unterklassen mitanpassen. -- Einverstanden!
- * Ein Klassenadapter kann nicht zur automatischen Anpassung von Unterklassen verwendet werden. -- Dito.
- * Klassenadapter lassen sich nur realisieren, wenn die Programmiersprache Schnittstellen oder Mehrfachvererbung unterstützt. -- Wieso das? Ich habe in Smalltalk öfter Klassenadapter gesehen, und auch in C++ lassen sie sich gut vorstellen, ohne daß Mehrfachvererbung benutzt wird. Das Design eines Klassenadapters besagt ja gerade, daß der Adapter die Zielklasse erbt, und zwar nur eine! Und was nützt einem da das Schnittstellenkonzept?
- Ich will aber keinen Editr-War anzetteln und lasse die Punkte daher erstmal so stehen. Viele Grüße! --Kuli 11:53, 10. Mär 2005 (CET)
- Klassenadapter erben ja von der Zielklasse UND vom Dienst. Das geht meiner Meinung nach nur, wenn man entweder Mehrfachvererbung oder Schnittstellen hat. Ansonsten nutzt du den Dienst über ein Attribut (d.h. in den Bildern eine Assoziation) für die Anbindung an den Dienst und hast damit einen Objektadapter. Der Name ist vielleicht das, was Dich in die Irre führt. Ein Objektadapter adaptiert genauso eine Klasse wie ein Klassenadapter. Die Bezeichnungen Klassenadapter und Objektadapter orientieren sich an den Kategorien der Klassenmuster und Objektmuster, wie sie die GoF aufstellt, siehe auch Entwurfsmuster#Klassifikation. Bei den Vorteilen des Klassenadapters geh ich mit Deiner Argumentation mit. Das Überschreiben bringt meiner Meinung nach Flexibilität, kann man aber in der Tat so sehen, dass man dann keinen Adapter mehr hat. Wobei der Verlust des Musters ja nichts über den Nutzen des Überschreibens aussagt. Der Vorteil der Anpassung genau einer Klasse will mir momentan auch nicht mehr einleuchten. --guwac 00:32, 11. Mär 2005 (CET)
- Nachtrag: Die Veränderung des Verhaltens scheint mir doch ganz vorteilig zu sein. Zunächst adaptiert ein Adapter eine inkompatible Schnittstelle eines Dienstes auf die einer Zielklasse. Durch Unterklassenbildung des Adapters kann man nun das Verhalten des Dienstes anpassen bzw. überschreiben und sich damit vom Dienst lösen. Bringt auf jeden Fall Flexibilität. Hingegen kann man gerade bei Diensten, die von Dritten geliefert werden, diese nicht durch Unterklassenbildung anpassen, da man keinen Quellcode hat. Dadurch ergibt sich auch der Vorteil der Anpassung genau einer Klasse. Hat der Dienst Unterklassen, die mitangepasst werden, kann ich nicht einfach durch Unterklassenbildung des Adapters das Verhalten des Dienstes überschreiben, da ich das (eventuell andere) Verhalten der Unterklassen mitüberschreibe. Da ich selbst das aber nochmal rekapitulieren musste, fehlt wohl eindeutig eine Erklärung dafür im Artikel. --guwac 00:41, 11. Mär 2005 (CET)
- Bingo! Jetzt habe ich geknallt, was Du sagen willst. Das verwirrende daran ist, daß das Diagramm zum Klassenadapter nicht zweifelsfrei definiert, daß der Adapter unbedingt die Zielklasse erben oder implementieren muß. Ich bin davon ausgegangen, daß der Adapter identisch sein kann mit der Zielklasse, dann braucht man eben keine Schnittstellen oder Mehrfachvererbung. Es ist natürlich immer eine Frage, wie streng man die Maßstäbe anlegt, die Gamma u.a. setzen; meiner Meinung nach ist beispielsweise eine Smalltalk-Unterklasse von Color, die die Methode green auf value mappt, um den Grünwert einer Farbe in einer GUI-Komponente darzustellen, durchaus ein gültiger Klassenadapter (allerdings auch ein arg konstruiertes Beispiel, in der Praxis würde man einen Objektadapter nehmen). Allerdings kann man auch argumentieren, daß Smalltalk implizit Schnittstellen besitzt, nämlich die, die durch den Aufrufer vorgegeben sind.
- Vielleicht sollte man den Text soweit erweitern, daß auch andere zu der Erleuchtung kommen. Mir selbst fehlt hiernach allerdings erstmal der Atem, aber bei Gelegenheit schreibe ich mal was dazu.
- Bei der Verhaltensänderung habe ich übrigens wieder einen Flüchtigkeitsfehler begangen, denn natürlich darf der Adapter das Verhalten der Zielklasse ändern. Vom Dienst dagegen sollte nur die SChnittstelle geändert werden. --Kuli 13:27, 14. Mär 2005 (CET)
- Wenn die Zielschnittstelle z.B. durch eine abstrakte Frameworkklasse vorgegeben wird, braucht man für den Klassenadapter zwingend Mehrfachvererbung. Wenn man frei im Entwurf ist, kann man natürlich die Abstrakte Zielklasse einfach mit dem Adapter verschmelzen. Das als Beispiel aufgeführte Szenario zweier inkompatibler Bibliotheken mit einem Adapter als Übersetzer lässt eine solche Freiheit z.B. aber nicht zu. Insofern ist es schon ein Nachteil des Klassenadapters. -- guwac 17:32, 14. Mär 2005 (CET)
Adapter = Wrapper???
BearbeitenHallo,
zunächst mal: Tolle Arbeit!!
Aber eine Frage habe ich noch: Grundsätzlich sind sich ja Wrapper und Adapter sehr ähnlich, es unterscheidet sie dennoch ein wichtiges Merkmal: Der Adapter sollte die gesamte Funktionalität der Hosts (also der adaptierten Klassen, Objekte) zur Verfügung stellen, aber auch nicht mehr, während beim Wrapper eben ein wenig mehr Freiheit herrscht, man also nur eine beschränkte Funktionalität zur Verfügung stellen, oder sie eben auch erweitern kann. Man kann also sagen, dass ein Adapter immer auch ein Wrapper ist, aber eben nicht umgekehrt. Daher wäre dann auch die Übersetzung von Adapter ins englische als Wrapper unpassend. Wenn ich an dieser Stelle etwas falsch verstanden habe, lasse ich mich gerne belehren!
Gruß heppa
Zusammengeführt mit Hüllenklasse
BearbeitenIch habe den Inhalt aus Hüllenklasse hier eingearbeitet, weil die Hüllenklasse m. E. nur ein anderer Name für den Objektadapter ist. --jpp ?! 12:44, 26. Jul 2006 (CEST) PS: Es folgt die originale Versionsgeschichte von Hüllenklasse zum Zeitpunkt der Einarbeitung.
- 2006-05-11 21:19 (diff) Mkleine (Artikel bereinigt und strukturiert, Absatz zum Autoboxing)
- 2006-04-18 19:34 (diff) (minor) Tim Helfensdörfer (RF)
- 2006-04-07 14:03 (diff) Kako
- 2005-05-31 19:02 (diff) 80.136.208.211 (anon) (um primitive Datentypen in Containern zu verwahren braucht man keine objektorientierte Programmierung)
- 2005-05-31 19:00 (diff) 80.136.208.211 (anon) (es heißt "Reflexion")
- 2005-05-31 18:56 (diff) 80.136.208.211 (anon) (Container sind nicht unbedingt objektorientiert)
- 2005-05-29 02:35 (diff) (minor) Sparti (kat)
- 2005-05-21 12:20 (diff) (minor) WhileTrue
- 2005-05-21 12:18 (diff) WhileTrue (rev.)
- 2005-05-21 09:57 (diff) 80.136.9.139 (anon)
- 2005-04-17 22:04 (diff) (minor) WhileTrue
- 2005-04-05 15:59 (diff) Stern
- 2005-04-05 11:58 (diff) (minor) ChristophDemmer
- 2005-03-10 06:47 (diff) (minor) CSonic (Link auf Datenkapselung)
- 2005-02-08 20:42 (diff) 80.141.58.164 (anon)
- 2004-10-16 17:01 (diff) (minor) D (reflection heißt das)
- 2004-09-12 15:11 (diff) 217.226.53.160 (anon)
- 2004-05-05 18:21 (diff) 62.138.203.76 (anon)
- 2004-05-05 18:05 (diff) 62.138.203.76 (anon)
Klassenadapter
BearbeitenHallo,
ich hab noch einen kleinen Nachtrag zu den Klassenadaptern. Wenn man das GoF-Buch aufmerksam liest, dann fällt auf dass das Beispiel zum Klassenadapter ein C++ Feature benutzt das sich private Vererbung nennt. Das bedeutet, dass die Implementierung der Superklasse und nicht deren Interface an die Subklasse vererbt wird. Dies halt also mehr mit "Komposition" astatt "echter Vererbung" zu tun. Der Adapter besitzt so trotz der Vererbung nur ein Interface. Sprachen wie Java unterstützen weder Mehrfachvererbung (auf Klassenebene) noch private Vererbung. Es ist zwar "möglich" ein dem Klassenadapter änliches Konstrukt zu schaffen (über Vererbung und Implementierung eines Interfaces) aber ziemlich sinnfrei, da die so erstellte Klasse beide Schnittstellen implementiert. Klassenadapter sind also nur dann sinnvoll, wenn die Sprache private Vererbung unterstützt.
Der Punkt kommt mir hier doch ein bissel zu kurz. Bin ich der Einzige der das so sieht?
Grüße, Ralf! (nicht signierter Beitrag von 217.91.7.234 (Diskussion) )
- Hi, unterschreibe deine Diskussionsbeiträge bitte immer mit „--~~~~“, dann bekommst du den Zeitstempel gratis. Zur Sache: Warum denkst du, dass eine Klasse, die zwei Schnittstellen implementiert, sinnfrei ist? Der Klient existiert ja normalerweise, bevor der Adapter implementiert wird (nur deshalb ist der Adapter ja nötig.) Also sollte der Klient auch nicht in Versuchung geraten, die falsche Schnittstelle zu verwenden. --j ?! 15:15, 21. Aug. 2008 (CEST)
- Ich sage ja nicht, dass es nicht funktioniert. Aber nicht immer ist alles was funktioniert auch sinnvoll. Die Beschreibung des Adapter-Patterns laut GoF ist "Convert the interface of a class into another interface clients expect" und nicht "Mix two interfaces together so that all clients can use them". Es geht also bei dem Pattern (wie bei den Andern auch) darum die Schnittstelle "sauber" zu halten. Das Pseudo-UML Diagram im Buch ist diese Vererbung auch mit "implementation" gekennzeichnet. --Ralfg 21:06, 21. Aug. 2008 (CEST)
- Sobald ich Zeit finde, werde ich mir den entsprechenden Abschnitt im Originalbuch nochmal durchlesen. Kannst aber auch gerne jetzt schon den Artikel entsprechend präzisieren. --j ?! 11:29, 22. Aug. 2008 (CEST)
Objektadapter
BearbeitenIm Artikel steht: >>> 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 Schnittstelle angepasst werden soll. <<< Den ersten Satz verstehe ich nicht. Mit dem zweiten ist wohl gemeint: "Ein Nachteil ist, dass die gesamte genutzte Schnittstelle des Adapters implementiert werden muss (im Gegensatz zum Klassenadapter, wo sie geerbt wird), auch wenn nur ein Teil der Schnittstelle des Dienstes angepasst werden soll." --Wikiplex 16:45, 9. Sep. 2009 (CEST)
- Der erste Satz ergab auch keinen Sinn. Die Schnittstelle muss unverändert bleiben, das ist ja der Sinn einer Schnittstelle. Gemeint ist wohl, dass die Schnittstelle auf andere Art implementiert werden soll. Ich habe deshalb ein Wort ersetzt. --j ?! 20:01, 9. Sep. 2009 (CEST)
- Hallo Jpp (Java plus plus?)! Na, der erste Satz ergibt auch jetzt noch keinen Sinn. :-) Wie wäre es, wenn wir den ganzen Abschnitt neu schreiben? Als Vorteile sehe ich, was GoF aufführt: Eine einzelne Adapter-Klasse kann viele Klassen adaptieren (alle, die vom Adaptierten ableiten). Wahrscheinlich ist genau das gemeint mit "Der Vorteil ist, dass der Adapter und der dahinterliegende Dienst ausgetauscht werden können". Des Weiteren ist ein Vorteil, dass man den Objektadapter in Sprachen benutzen kann, die keine Mehrfachvererbung kennen, um den Klassenadapter zu simulieren (wenn nur öffentliche Methoden aus dem Adaptierten benutzt werden). Als Nachteil sehe ich, was schon im Artikel steht, und was GoF angibt: Das Verhalten des Adaptierten ist schwerer zu überschreiben, weil man eventuell eine Subklasse vom Adaptieren bilden muss (wobei das IMHO nur ein sekundärer Vorteil ist, der einem beim Klassenadapter durch die dort ohnehin notwendige Vererbung geschenkt wird).
- BTW: Ich mache mich mal auf die Suche nach einem konkreteren Beispiel. Was da als C++-Beispiel steht ist ja nichts anderes als die UML-Diagramm-Struktur in Code übersetzt. Viele Grüße! --Wikiplex 11:14, 10. Sep. 2009 (CEST)
Geschwindigkeit
Bearbeitenzu „Hüllenklassen für primitive Datentypen“, „Die einfache Schreibweise und bessere Lesbarkeit geht auf Kosten einer erheblich schlechteren Ausführungsgeschwindigkeit.“
Sofern man dort, wo nur int
benötigt wird (Schleifenzähler o.ä.) auch nur selbiges verwendet, und nur Integer
, wo es unumgänglich ist, sollte keine merkliche Verlangsamung eintreten - allenfalls bei einem Interpreter; aber heutige VM sind eh' immer JIT (oder noch ausgefuchsteres)...
Wenn der Programmierer natürlich IMMER Integer
Objekte verwendet, auch bei Schleifen/Berechnungen/..., dann muss der Interpreter schon kämpfen (sofern der zu-Bytecode-Compiler nicht optimiert hat). --arilou 11:31, 13. Apr. 2011 (CEST)
Beispiele in Java
BearbeitenLaut diesem Beitrag sind folgende Elemente aus Java Adapter:
- java.io.InputStreamReader(InputStream) - (returns a
Reader
) - java.io.OutputStreamWriter(OutputStream) (returns a
Writer
) - javax.xml.bind.annotation.adapters.XmlAdapter#marshal() and #unmarshal()
Kann mir das jemand erklären? Was ist der Klient, was der Adapter, was ist der Dienst? Was sind jeweils die Operationen? --Martin Thoma 11:54, 17. Jul. 2012 (CEST)
- Klient ist der, der das Ganze benutzt. Eine Klasse
MyProgram
beispielsweise. Ziel istReader
, Adapter istInputStreamReader
und Dienst istInputStream
. Das ist eigentlich ziemlich klar, schätze ich. Das Pattern wird genau so verwendet, wie es im GoF-Book steht. Umgekehrt gibt es aber andere Patterns, die in abgewandelter Form verwendet werden. Im von dir verlinkten Beitrag wird z.B. behauptet,Arrays.asList()
wäre eine AbstractFacttory. Inwieweit das so richtig ist, darüber könnte man sich streiten. Strukturell ist es nicht so. Da aber bei Patterns die Struktur eben nicht alles ist, könnte es ja immer noch eine Variante des Patterns sein. Dafür müsste aber die Intention zumindest die selbe sein. Das würde ich in dem Fall aber in Zweifel ziehen. Hier aber bei den Adaptern ist es ziemlich klar. Nur beim Beispiel mit demXMLAdapter
haben wir ne Variante des Patterns, die strukturell abweicht (aber die selbe Intention hat). --Der Hâkawâti ✉ 10:05, 18. Jul. 2012 (CEST)- Vielen Dank für die ausführliche Antwort! Ich habe noch das Bild hinzugefügt, falls jemand anderes die gleichen Fragen hat. --Martin Thoma 13:16, 18. Jul. 2012 (CEST)
Teil-Revert 27.7.2012
BearbeitenSiehe hier.
- Die bessere Verlinkung der Gang of Four ist ok.
- Dass jedes bischen Code in eine Vorlage {{Java|...}} o.ä. verpackt wird, ist
- übertrieben, das normale <code> erledigt das für alle Programmiersprachen ganz passabel, und
- auch ist diese Vorlagen-Bomberei auch nicht gerade anfängerfreundlich - ein WP-Neuautor kennt (hoffentlich) etwas Html, aber dann auch noch die ganze Vorlageritis, nenene.
--arilou (Diskussion) 08:47, 27. Jul. 2012 (CEST)
- Ich würde noch ein Argument ergänzen:
- Auch aus Sicht des Lesers erscheint es mir nicht gerade hilfreich, in einem erläuternden Fließtext praktisch willkürlich immer mal wieder Fragmente bunt hervorzuheben. Warum muss ein simples
int
mitten im Text bunt sein? Warum der KlassennameKreis
? Ich finde, das verwirrt mehr, als es hilft.
- Auch aus Sicht des Lesers erscheint es mir nicht gerade hilfreich, in einem erläuternden Fließtext praktisch willkürlich immer mal wieder Fragmente bunt hervorzuheben. Warum muss ein simples
- --TMg