240 likes | 464 Views
Besucher Muster. Sebastian Grahn Sebastian Kühn. Zweck Anwendbarkeit Struktur Teilnehmer Interaktionen. Vor- & Nachteile Implementierung Beispiele Bekannte Verwendung Verwandte Muster. Gliederung. 1. Zweck. Kapselung einer auf Elementen einer Objektstruktur auszuführenden Operation
E N D
Besucher Muster Sebastian Grahn Sebastian Kühn
Zweck Anwendbarkeit Struktur Teilnehmer Interaktionen Vor- & Nachteile Implementierung Beispiele Bekannte Verwendung Verwandte Muster Gliederung
1. Zweck • Kapselung einer auf Elementen einer Objektstruktur auszuführenden Operation • Ermöglicht Definition neuer Operationen ohne Klassen der von ihr bearbeiteten Elemente zu verändern
2. Anwendbarkeit Das Besuchermuster kann verwendet werden, wenn: • viele unterschiedliche, nicht verwandte Operationen auf einer Objektstruktur realisiert werden sollen. • sich die Klassen der Objektstruktur nicht verändern. • häufig neue Operationen auf der Objektstruktur integriert werden müssen. • ein Algorithmus über die Klassen einer Objektstrukur verteilt arbeitet, aber zentral verwaltet werden soll.
4. Teilnehmer (I) • Besucher : • definiert für jede Klasse konkreter Elemente eine Besuchsfunktion • kann unter Verwendung der konkreten Schnittstelle auf das Element zugreifen • KonkreterBesucher : • implementiert in Besucherklasse deklarierte Besuchsfunktionen • jede Besuchsfunktion ist ein Fragment des Algorithmus für die gesamte Objektstruktur • lokaler Zustand als Kontext für den Algorithmus (enthält häufig Ergebnisse)
4. Teilnehmer (II) • Element : • definiert eine Schnittstelle zum Empfang eines Besuchers (NimmEntgegen-Operation) • KonkretesElement : • implementiert den Empfang eines Besuchers (NimmEntgegen-Operation)
4. Teilnehmer (III) • ObjektStruktur : • Kann seine Elemente aufzählen • Evtl. abstrakte Schnittstelle, die Besucher erlaubt Elemente zu besuchen • Kann Kompositionsmuster oder Behälter (Liste oder Menge) sein
5. Interaktionen (I) • Klient erzeugt KonkretesBesucher-Objekt und traversiert Objektstruktur, wobei es jedes Element mit Besucher besucht • Wenn Element besucht wird, ruft es die seiner Klasse entsprechenden Operationen auf und übergibt sich selbst als Argument damit Besucher auf Zustand zugreifen kann
6. Vor- & Nachteile • Vorteile : • Neue Operationen lassen sich leicht durch die Definition neuer Besucher hinzufügen • Verwandte Operationen werden im Besucher zentral verwaltet und von besucherfremden Operationen getrennt • Besucher können über mehreren Klassenhierarchien arbeiten • Nachteile : • Neue Klassen konkreter Elemente erfordern Erweiterungen in allen Besuchern
7. Implementierung (I) • Besucherklasse class Besucher { puplic: virtual void BesucheElementA(ElementA*); virtual void BesucheElementB(ElementB*); //und so weiter für die anderen konkreten //Elementklassen protected: Besucher(); };
7. Implementierung (II) • Konkrete Elementklassen class Element { puplic: virtual ~Element(); virtual void NimmEntgegen(Besucher&) = 0; protected: Element(); };
7. Implementierung (III) class ElementA : puplic Element { ElementA(); virtual void NimmEntgegen(Besucher& Besucher) { besucher.BesucheElementA(this); }; }; class ElementB : puplic Element { ElementB(); virtual void NimmEntgegen(Besucher& Besucher) { besucher.BesucheElementB(this); }; };
7. Implementierung (IV) • Implementierungsaspekt (I) • Double-Dispatch • ausgeführte Operation hängt von Art der Anfrage und den Typen zweier Empfänger ab • NimmEntgegen hängt ab vom Typ des Besucher und dem des Elements Verwendung Double-Dispatch ( z.B. CLOS) • Single-Dispatch (Zur Erläuterung) • ausgeführte Operation hängt von Namen der Anfrage und Typ des Empfängers ab (z.B. C++)
7. Implementierung (V) • Implementierungsaspekt (II) • Zuständigkeit für Traversierung • Besucher muss jedes Element der Objektstruktur besuchen • Zuständigkeit der Traversierung an 3 Stellen möglich: in Objektstruktur, im Besucher oder in einem Iterator (siehe Vortrag) • Häufig in Objektstruktur durch einfache Iteration über Elemente (Behälter) • In Besucher wenn komplexe Traversierung, die von Ergebnissen von Operationsaufrufen abhängt
8. Beispiel • Virtuelles Reisebüro - verschiedene Busreisen, Ferienhäuser und Mietwagen mit Beschreibung, Preiskategorie (Sommer/Winter), Bilder und technische Daten - Preise der Kategorien sind in einem Preismodul gespeichert - die Klassen für Busreisen, Ferienhäuser, Mietwagen und Preismodul enthalten Schnittstelle zum Empfang eines Besuchers - ein Kunde stellt eine Reise zusammen
Kunde möchte Gesamtpreis erfahren: • Ein Besucher besucht die interessierenden Objekte mit Hilfe eines • Zählers und fragt die jeweilige Kategorie ab • Zuletzt berechnet er im Preismodul mit Hilfe seiner lokal gesammelten • Informationen den Gesamtpreis Kunde will Reise buchen: - Ein anderer Besucher erstellt Reisebestellung… • dazu besucht er alle, den Kunden interessierenden Objekte… • Sein lokaler Zustand besteht aus einem Dokument, dass • er gemäß der Informationen der Objekte gestaltet • - Beim besuch des Preismoduls ergänzt er die Preise dazu
9. Bekannte Verwendungen • Smalltalk80-Übersetzer • Besucherklasse : ProgramNode-Enumerator • Hauptsächlich zur Analyse von Quelltexten • IRIS-Inventor [Str93] • Entwicklung von 3D-Anwendungen • Hierarchie von Knoten (geometrische Objekte oder Attribut eines geom. Objekts) • Besucher : Actions • Zur Auswertung, zur Ereignisbehandlung, zum Suchen, zum Speichern und zum Bestimmen von Begrenzungsrahmen
10. Verwandte Muster • Kompositionsmuster • Um Operationen auf eine mit Hilfe des Kompositionsmusters definierte Struktur anzuwenden • Interpreter • Die Interpretation einer Objektstruktur als ein Interpreter auszuführen
ende Vielen Dank für Ihre Aufmerksamkeit... ... Und einen angenehmen Feierabend.
Zusatz (I) • Public Class Busreise {… void nimmentgegen(Besucher b) { b.Busreisebesucher(this); }} • public Class Ferienhaeuser… Void nimmentgegen (Besucher b) { b.Ferienhausbesucher(this); }} • public Class Mietwagen {… void nimmentgegen (Besucher b) { b.Mietwagenbesucher(this); }}
Zusatz (II) • public Class Besucher { Void Busreisbesucher(Busreise b); Void Ferienhausbesucher(Ferienhaus f); Void Mietwagenbesucher(Mietwagen m);} • Public Class Gesamtpreisbesucher implements Besucher {Gesamtpreisbesucher();int GibGesamtPreis();int gesamt=0;Void Busreisebesucher(busreise b) { gesamt += b.getPreis();}Void Ferienhausbesucher(Ferienhaus f) { gesamt += f.getPreis();}Void Mietwagenbesucher(Mietwagen m) { gesamt += m.getPreis();}