Diskussion:Besucher (Entwurfsmuster)
Wie saehe denn eine Funktionserweiterung in dem beschriebenen Beispiel aus?
Ja, eine UML-Notation zu den Beispielen wäre sicherlich recht hilfreich!
Die englischen Bezeichner (vielleicht einen Link in's englische Wikipedia?)
waeren auch ganz hilfreich, vielleicht bin ich ja auch nur zu dumm zu finden...
Ich bin mit den englischen Begriffen besser vertraut.
Das Beispiel "Virtuelles Reisebüro" ist meiner Meinung nach schlechtes Design. Ein Visitor sollte normalerweise nie Annahmen gegenüber der Struktur machen, die er besucht - er kann gewisse Typen besuchen, die Reihenfolge dabei sollte aber frei bestimmt werden können. In dem Beispiel wird davon ausgegangen, dass das Preismodul immer zuletzt besucht wird. Dies macht das Design fragil. Eine bessere Lösung wäre es, den Visitor vor seiner Besuchstour mit einem Preismodul zu initialisieren (z.B. auch gleich per Konstruktor).
Sind die beiden Kontra-Argumente nicht identisch?
Seitenverschiebung von Besucher (Entwurfsmuster) nach Visitor
BearbeitenAm 16. März 2008 hat Benutzer:D den Artikel von Besucher (Entwurfsmuster) nach Visitor verschoben mit der Begründung „Begriffsbildung“. Ich sehe hier keine Begriffsbildung, Besucher und Besuchermuster sind genau die in der deutschen Übersetzung des Entwurfsmuster-Buches der Viererbande und in diversen anderen deutschsprachigen Veröffentlichungen verwendeten Begriffe. Im Gegenteil scheint mir Visitor im deutschen Sprachgebrauch eher unüblich zu sein. Meiner Meinung nach sollte die Seitenverschiebung rückgängig gemacht werden. —Tobias Bergemann 09:19, 17. Mär. 2008 (CET)
- Auf jeden Fall sollte das Lemma von "Visitor" zumindest auf "Visitor (Entwurfsmuster)" geändert werden. "Visitor" als solches ist ein englisches Wort das einen "Besucher" im allgemeinen Sinn betrifft und nicht ein Design Pattern. Abgesehen davon werden die meisten (wenn nicht gar alle) hier gelisteten Design Patterns alle mit nachgestelltem, eingeklammerten "Entwurfsmuster" gekennzeichnet. Meiner Meinung nach sollte diese Seite hier im besten Fall eine Begriffsunterscheidung zu "Besucher" und "Besucher (Entwurfsmuster)" beinhalten.Henning Schaefer (???, +/-) 16:38, 20. Mai 2008 (CEST)
- Ich bin auch für eine Zurückbenennung. Mit "Besucher (Entwurfsmuster)" entspräche das Lemma dem Standard aller Entwurfsmusterseiten in der deutschsprachigen Wikipedia: "<eingedeutschter Name> (Entwurfsmuster)" bei gleichzeitiger Nennung des englischen Namens in der Einleitung. Ich werde diese Änderung bald vornehmen.--83.65.37.102 21:11, 12. Jun. 2008 (CEST)
Also erstmal: der Artikel sollte unter dem gebräuchlicheren aller möglichen (korrekten) Bezeichnungen stehen.
@Tobias Bergemann: Kurzer google test: 300 000 für "Entwurfsmuster Visitor", 14 000 für "Entwurfsmuster Besucher". Google ist nicht der Weißheit letzter Schluss, aber doch ein gutes Indiz, denke ich. Aber man kann durchaus mal gucken, wie das in der Fachliteratur aussieht.
@Hschaefer: Klammerzusätze werden per Konvention angehängt, wenn das notwendig ist, weil es schon einen Arikel mit dem Namen ohne Zusatz gibt. Nur der Einheitlichkeit halber einen Klammerzusatz anzuhängen halte ich für sinnlos und ist auch unüblich. Und auch Link ist "nur eine englisches Wort", genau wie Cookie -- als Lehnwort haben die halt eine Spezialbedeutung. Das ist oft so.
@83.65.37.102: ich hoffe, du nimmst die vor, wenn du eingeloggt bist -- als IP geht nur copy&paste, das wäre nicht gut. Jedenfalls... mir scheint eine derartige "Vereinheitlichung" widersinning. Gerade im IT-Bereicht (oder muss ich EDV sagen?) gibt's halt viele aus dem englischen entliehenen Begriffe. Für manche Dinge ist die englische Bezeichnung üblich (Computer, Browser, Mail), für andere die deutsche (Bildschirm, Maus, Tastatur). Zu versuchen, durchgängig nur die englischen oder nur die deutschen Bezeichnungen zu verwenden, wäre künstlich und schädlich. Es kommt auf den Einzelfall an.
Also: nach meinen Sprachgefühlt ist "Visitor" besser weil gebräuchlicher. Ob es wirklich gebräuchlicher ist, wäre zu untersuchen. Die anderen Argumente finde ich allerdings nicht stichhaltig. In jedem Fall sollen beide bezeichnungen im Artikel erwähnt werden und durch Redirects bzw. Begriffsklärungen abgedeckt sein. -- Duesentrieb ⇌
- Ich bin auch für eine Rückverschiebung aus folgenden Gründen:
- 1. Konsistenz: Wir haben momentan deutsche und englische Begriffe für die Entwurfsmuster gemischt. Das sollte vereinheitlicht werden.
- 2. Gebräuchlichkeit: Wie Duesentrieb schon geschrieben hat, ist Google "nicht der Weißheit letzter Schluss". Eine einfache Google-Suche nach einem Fachwort ist nicht der passende Weg. Relevant sind nur Fachbücher, was z.B. ich in meinem Blog schreibe sollte nicht relevant sein. Also Google Books. Aber auch hier ist eine einfache Suche nicht so gut geeignet. Einige Autoren, die den deutschen Begriff verwenden, deuten auch auf das englische "original" hin. Da die Entwurfsmuster der GoF entstammen, sollten wir uns nicht anmaßen eine bessere Übersetzung zu finden, als das professionell übersetzte Buch Entwurfsmuster (Buch). Wenn das Buch hier keine Relevanz hat, wo dann? In diesem Fall bitte ich um eine Löschung des Artikels "Entwurfsmuster (Buch)" wegen fehlender Relevanz. (auf die Diskussion bin ich gespannt).
- In der Vorlesung "Softwaretechnik" am Karlsruher Institut für Technologie werden übrigens konsistent die deutschen Begriffe verwendet, aber auf die Englischen hingewiesen.
- 3. Deutsche Wikipedia: Dies ist die deutsche Wikipedia. Wenn gute Begriffe im deutschen Existieren, die im deutschen durchaus üblich sind - wenn auch zugegebenermaßen seltener - dann ist das meiner Meinung nach keine Begriffsbildung. Da die englischen Begriffe auch üblich sind, sollte dennoch auf sie hingewiesen werden.
- 3.1 Lesbarkeit: Ein Text mit einer Mischung aus englischen und deutschen Wörtern ist schwerer zu lesen.
- 3.2 Verständnis: Die Wikipedia:Allgemeinverständlichkeit ist mit deutschen Begriffen leichter herzustellen. Warum wird das Entwurfsmuster "Visitor" genannt? Ich finde, obwohl es ein sehr einfaches englisches Wort ist, kann man in der deutschen Wikipedia nicht erwarten, dass es dem Leser bekannt ist. Mit dem Begriff "Besucher" assoziiert der Leser etwas, mit "Visitor" nicht.
- Also zusammenfassend: Ich bin (bei allen GoF-Entwurfsmustern) für die Benutzung der Begriffe der Übersetzung Entwurfsmuster (Buch). --Martin Thoma 09:09, 19. Jul. 2012 (CEST)
- Kleine Anmerkung - dies ist nicht die deutsche Wikipedia, sondern die deutschsprachige Wikipedia.--Sebastian.Dietrich ✉ 18:43, 4. Nov. 2012 (CET)
note to self
Bearbeitenein visitor dient mehr oder weniger dazu, double dispatch zu implementieren, wenn die sprache von sich aus nur single dispatch anbietet. -- ∂ 21:31, 12. Jun. 2008 (CEST)
Fehler
Bearbeiten- Innerhalb des Kontra-Punktes: "Müssen neue konkrete Elemente hinzugefügt werden, so führt dies dazu, dass enorm viele Besucher-NimmEntgegegen-Methoden implementiert werden müssen." - müsste es hier nicht "Besucher-besuche-Methoden" heißen? -- neogrande 11:08, 09. Sep. 2008 (CEST)
Bildbeschreibung fehlt bei [[Bild:Besucher.png]]
BearbeitenDer Artikel enthält ein Bild, dem eine Bildbeschreibung fehlt, überprüfe bitte, ob es sinnvoll ist, diese zu ergänzen. Gerade für blinde Benutzer ist diese Information sehr wichtig. Wenn du dich auskennst, dann statte bitte das Bild mit einer aussagekräftigen Bildbeschreibung aus. Suche dazu nach der Textstelle [[Bild:Besucher.png]] und ergänze sie.
- Wenn du eine fehlende Bildbeschreibung ergänzen willst, kannst du im Zuge der Bearbeitung folgende Punkte prüfen:
- Namensraum Datei: Bilder sollte im Namensraum Datei liegen. Bitte ändere die alten Bezeichnungen
Bild:
undImage:
inDatei:
. - Skalierung: Außerhalb von Infoboxen sollten keine festen Bildbreiten (zum Beispiel 100px) verwendet werden. Für den Fließtext im Artikelnamensraum gibt es Thumbnails in Verbindung mit der automatischen Skalierung. Um ein Bild/eine Grafik in besonderen Fällen dennoch größer oder kleiner darzustellen, kann der „upright“-Parameter verwendet werden. Damit erfolgt eine prozentuale Skalierung, die sich an den Benutzereinstellungen orientiert. --SpBot 11:02, 2. Mär. 2009 (CET)
- Namensraum Datei: Bilder sollte im Namensraum Datei liegen. Bitte ändere die alten Bezeichnungen
UML
BearbeitenDie Assoziationen im UML sind nicht korrekt, die Implementation eines Interfaces wird m.E. nicht durch eine durchgezogene, sondern durch eine gestrichelte Linie dargestellt. Desweiteren würde ich eine klarere Kennzeichnung der Interfaces als solche vorschlagen. Wiebketru (Diskussion) 17:38, 1. Jun. 2012 (CEST)
Die Implementation eines Interfaces wird nicht mit einer Assoziation dargestellt, ansonsten ist es richtig, dass eine gestrichelte Linie für eine InterfaceRealization verwendet werden würde. Allerdings würde ich hier keine Interfaces benutzen. Der abstrakte Besucher und das abstrakte Elemente könnten durchaus auch Implementierung enthalten, daher sind abstrakte Klassen das richtige Element. --AxelScheithauer (Diskussion) 21:22, 3. Apr. 2020 (CEST)
Beispiel falsch oder zumindest verwirrend
BearbeitenWie beim englischen Artikel diskutiert, ist das Beispiel in einem Punkt seltsam: Meiner Ansicht nach müsste Car
ebenfalls von CarElement
erben und eine accept
-Funktion anbieten, die die accept
-Funktionen seiner
element
e aufruft.
Alternativ sollte irgendwo eine Funktion VisitCar(Car c, Visitor v)
existieren, die das Aufrufen der einzelnen accept
-Funktionen ermöglicht.
Denn die aktuelle Implementierung verletzt das DRY-Prinzip. (nicht signierter Beitrag von 93.190.250.146 (Diskussion | Beiträge) 10:05, 22. Jul 2009 (CEST))
Vielleicht wäre es sinnvoller, würde man das Codebeispiel an das zuvor genannte "Virtuelles Reisebüro" anlehnen. Der Nachvollziehbarkeit und dem Lerneffekt würde es ohne Zweifel dienen, Theorie und "Praxis" sich entsprechend ergänzen. -- 188.109.12.175 11:29, 15. Jul. 2010 (CEST)
Ich empfinde das Beispiel auch als falsch, da ein Besucher "herumgeführt" werden muss, d.h. die ObjektStruktur (hier Car, CarElement usw.) ist dafür verantwortlich, untergeordnete accepts aufzurufen. (nicht signierter Beitrag von 87.193.196.98 (Diskussion) 10:45, 28. Apr. 2011 (CEST))
Die englischsprachige Wikipedia hat das Beispiel bereits verbessert. Ich traue mich nur nicht Copy&Paste zu machen. Das DRY-Prinzip wird nun nicht mehr verletzt. (nicht signierter Beitrag von 134.96.208.100 (Diskussion) 15:18, 8. Jun. 2011 (CEST))
Erklärungsversuch
BearbeitenEs ist schon im Ansatz richtig, allerdings sollte das Beispiel etwas verändert werden, um die Verwirrung zu beseitigen.
Die Klasse Car repräsentiert kein konkretes Element (CarElement) sondern entspricht der Klasse "Objektstruktur" im UML Diagramm, die eine Liste von CarElementen (also Wheel, Engine oder was auch immer) kennt.
Diese Klasse ruft bei Bedarf die accept(besucher) methoden für all seine Elemente auf.
for(CarElement carElement : car.getElements()) { carElement.accept(this); }
da das car-objekt nicht selbst in der Liste vertreten ist (es ist ja der Einstiegspunkt), braucht es die accept methode auch nicht implementieren! Ausserdem erbt Sie auch nicht von der Schnittstelle CarElement und ist deshalb eh nicht gezwungen, die Methoden des Interfaces (hier ist es nur die accept Methode) zu implementieren.
Halten wir fest: Die Klasse Car ist von den anderen Klassen wie "Wheel, Engine" etc. abzuheben, da Sie NICHT von der Abstrakten Klasse Element (siehe UML) erbt, sondern der Klasse Objektstruktur enspricht und somit auch NICHT von den Besuchern besucht wird. Sie bietet lediglich den "Wurzelknoten" wenn man so will, der benötigt wird, damit die Traversierung der Struktur durch Besucher angestoßen werden kann. (siehe for-schleife von oben)
Das einzig verwirrende ist, dass die methode
void visitCar(Car car)
im Visitor Interface definiert worden ist, wo Sie eigentlich nicht hingehört. Weil wie oben erwähnt, die Klasse Car nicht zu der zu Traversierenden Objektstruktur selbst gehört, sondern diese lediglich "kennt" und als Einstiegspunkt fungieren soll.
Es funktioniert natürlich, so wie es im Beispiel gezeigt ist, allerdings würde ich Vorschlagen, die Methode visitCar(Car car) aus dem Interface Visitor zu entfernen, sowie aus den Klassen, die die Schnittstelle implementieren (DoVisitor und PrintVisitor).
Den Algorithmus, zum Aufrufen der accept methoden (oben genannte for-schleife) sollte dann ganz unten in der Klasse VisitorDemo erfolgen.
-- Simon Schaper (nicht signierter Beitrag von 80.171.73.23 (Diskussion | Beiträge) 09:34, 12. Aug. 2009 (CEST))
Außerdem
BearbeitenAußerdem lassen sich mit einem Vistor sehr elegant komplizierte if-Statements in Abhängigkeit des Typs vermeiden:
Mit Typecast:
interface IFamilyMember {} class Father : IFamilyMember {} class Mother : IFamilyMember {}
static void Main()
{
IFamilyMember[] myfamily = { new Father(), new Mother() };
if (myfamily[0] is Father)
{
Console.WriteLine("This is the family's father.");
}
else if (myfamily[0] is Mother)
{
Console.WriteLine("This is the family's mother.");
}
}
Ohne Typecast:
interface IFamilyMember
{
void accept(Visitor v);
}
class Father : IFamilyMember
{
public void accept(Visitor v)
{
v.print(this);
}
}
class Mother : IFamilyMember
{
public void accept(Visitor v)
{
v.print(this);
}
}
class Visitor
{
public void print(Father f)
{
Console.WriteLine("This is the family's father.");
}
public void print(Mother m)
{
Console.WriteLine("This is the family's mother.");
}
}
static void Main()
{
IFamilyMember[] myfamily = { new Father(), new Mother() };
myfamily[0].accept(new Visitor());
}
Et voilà: Keine Casts mehr im Programm! :D Paradrop 18:48, 3. Mär. 2010 (CET)
- Prinzipiell hast du recht. Das Problem bzw. die Lösung ist allerdings etwas komplexer. Dein Beispiel ist zwar technisch korrekt, suggeriert aber ein falsches Problem. In so einem Fall würde man wohl eher IFamilyMember ne print() Methode verpassen und in Father und Mother entsprechend implementieren.
- Das eigentliche Problem ist das Fehlen von Multiple Dispatch in den meisten OO-Sprachen. Das muss man irgendwie ausgleichen. Eine Möglichkeit sind dynamische Typprüfungen. Und eine andere - bessere - Lösung ist das Visitor-Pattern.
- Das ist technisch betrachtet das, was du hier vorführst. Allerdings ist die dynamische Typprüfung "nur" das Symptom... --Der Hâkawâti ✉ 22:23, 3. Mär. 2010 (CET)
Was soll der Mist
BearbeitenWelcher Dödel ist auf die Idee gekommen lokale Variablennamen groß zu schreiben? Das ist Javacode und keine Skriptsprache!
Der Javabeispielcode von früher war wesentlich besser, auch von der Formatierung und Semantik. Warum kann hier jeder daherkommen und seinen Mist verbreiten? (nicht signierter Beitrag von 93.200.219.130 (Diskussion) 02:55, 3. Nov. 2012 (CET))
- Die Antwort auf deine Frage ist einfach: Wiki-Prinzip. --Sebastian.Dietrich ✉ 18:40, 4. Nov. 2012 (CET)
Beispiel gelöscht
BearbeitenWikipedia ist keine Sammlung von Codebeispielen. Wenn schon Code, dann kurz und knackig. Das Beispiel war alles andere als kurz und knackig, darüberhinaus auch noch von den Naming-Conventions etc. her umstritten (siehe Beiträge weiter oben). Wenn dann bitte ein möglichst kurzes Beispiel basierend auf den (allgemein auch befolgten) Java Naming Conventions. --Sebastian.Dietrich ✉ 18:39, 4. Nov. 2012 (CET)
Thema verfehlt
BearbeitenWenn ich die englische Version dieses Artikels mit der deutschen Version vergleiche, dann wundere ich mich darüber, dass beide das selbe Thema abhandeln sollen.
Aus der deutschen Version geht ein völlig anderes Kernkonzept aus der Beschreibung hervor als es bei der englischen der Fall ist.
Im Übrigen habe ich sogar den Eindruck, dass in der Beschreibung der deutschen Version lediglich eine ganz ordinäre Schichtentrennung beschrieben wird.
Der Kern des Besuchermodells ist nämlich nicht, beliebig viele disjunkte Funktionen auf Objekten auszuführen, sondern dass zwei oder mehr konkrete, aber polymorphe Objekte zur Laufzeit sich gegenseitig ihre aktuellen Laufzeittypen übermitteln (vtable etc.), damit eine konkrete Funktion mit den jeweiligen Laufzeittypen aller Objekte arbeitet. Und eben genau das ist nur notwendig, wenn eine Sprache dies nicht nativ unterstützt.
Aber eben dies geht aus der deutschsprachigen Version dieses Artikels leider nicht hervor. --My2Cents (Diskussion) 12:19, 14. Jan. 2015 (CET)
- Danke dass du dich des Artikels annehmen wirst und dies auch bequellt einbauen wirst. --Sebastian.Dietrich ✉ 20:16, 14. Jan. 2015 (CET)