Muster: Visitor

Aus Wikibooks

Besucher[Bearbeiten]

Der Besucher gehört zu der Kategorie der Verhaltensmuster (Behavioural Patterns). Es dient zum Kapseln von Operationen, die auf Elementen einer Objektstruktur ausgeführt werden. Neue Operationen können dadurch ohne Veränderung der betroffenen Elementklassen definiert werden.

Verwendung[Bearbeiten]

Die Integration verschiedener nicht miteinander verwandter Operationen in die Klassen einer Objektstruktur gestaltet sich oft schwierig. Bei der Erweiterung um neue Operationen müssen alle Klassen erweitert werden. Das Besuchermuster lagert die Operationen in externe Besucherklassen. Dazu müssen die zu besuchenden Klassen jedoch eine Schnittstelle zum Empfang eines Besuchers definieren.

Generell empfiehlt sich die Verwendung von Besuchern, 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 oder
  • ein Algorithmus über die Klassen einer Objektstrukur verteilt arbeitet, aber zentral verwaltet werden soll.

UML-Diagramm[Bearbeiten]

Akteure[Bearbeiten]

  • Besucher
    • definiert für jede Klasse konkreter Besucher eine Besuchsfunktion
  • KonkreterBesucher
    • implementiert Besuchsfunktionen
    • jede Besuchsfunktion ist ein Fragment des Algorithmus, welcher auf der gesamten Objektstruktur angewendet wird
    • lokaler Zustand dient als Kontext für den Algorithmus
  • Element
    • definiert eine Schnittstelle zum Empfang eines Besuchers
  • KonkretesElement
    • implementiert den Empfang eines Besuchers
  • ObjektStruktur

Pro[Bearbeiten]

  • 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.

Kontra[Bearbeiten]

  • Die gute Erweiterungsmöglichkeit der Klassen von Besuchern muss mit einer schlechten Erweiterbarkeit der Klassen der konkreten Elemente erkauft werden. Müssen neue konkrete Elemente hinzugefügt werden, so führt dies dazu, dass enorm viele Besucher-NimmEntgegegen-Methoden implementiert werden müssen.
  • Neue Klassen konkreter Elemente erfordern Erweiterungen in allen Besuchern.

Beispiele[Bearbeiten]

Virtuelles Reisebüro[Bearbeiten]

Ein Reiseveranstalter bietet seinen Kunden verschiedene Busreisen, Ferienhäuser und Mietwagen an. Jedem Objekt sind eine Beschreibung und eine Preiskategorie für Sommer und Winter zugewiesen. Die Preise der Kategorien sind in einem Preismodul gespeichert. Bei Ferienhäusern sind darüber hinaus Bilder, bei Mietwagen technische Daten abgelegt. Sowohl die Klassen für Busreisen, Ferienhäuser und Mietwagen, als auch das Preismodul bieten eine Schnittstelle zum Empfang eines Besuchers. Das Preismodul ist außerhalb der Klassenhierarchie von Busreisen, Ferienhäusern und Mietwagen.

Ein Kunde kann sich nun eine Reise zusammenstellen. Fragt er dann nach dem Gesamtpreis, so besucht ein Besucher zunächst die interessierenden Objekte, fragt die jeweilige Kategorie ab. Für jede Kategorie verwaltet er einen lokalen Zähler. Zuletzt besucht er das Preismodul und berechnet auf Grund der dort abgelegten Preise und seiner lokal gesammelten Informationen den Gesamtpreis.

Entscheidet sich der Kunde, die Reise zu buchen, kann ein anderer Besucher eine Reisebestätigung erstellen. Dazu besucht er wieder die den Kunden interessierenden Objekte und das Preismodul. Sein lokaler Zustand besteht aus einem Dokument, das er gemäß den Informationen der Objekte gestaltet. Bei allen Objekten listet er zunächst die Beschreibung und die Preiskategorie auf, bei Mietwagen zusätzlich die technischen Daten. Beim Besuch des Preismoduls ergänzt er dann die einzelnen Beschreibungen um die konkreten Preise.

Beide Besucher übergreifen Klassenhierarchien, da sie sowohl auf der Klassenhierarchie der buchbaren Reiseelemente als auch auf dem Preismodul arbeiten.

Besucher in Compiler (Übersetzern)[Bearbeiten]

Im Compilerbau liegt nach der syntaktischen Analyse meist ein abstrakter Syntaxbaum vor. Ein solcher Baum lässt sich durch Klassen für die verschiedenen Elemente und Verwendung von Aggregationen gut als Objektstruktur beschreiben. Auf dieser Objektstruktur kann man nun einen allgemeinen Besucher definieren, der den Baum traversiert. Dazu werden bei der Implementierung der Besuchsfunktion für eine Elementklasse des Baums die aggregierten Elemente nacheinander besucht. Von diesem allgemeinen Besucher lassen sich nun verschiedene Besucher ableiten, die unterschiedliche Operationen auf dem abstrakten Syntaxbaum implementieren.

In einem Besucher lässt sich die semantische Analyse realisieren. Dazu besucht dieser die Elemente des Baums und erweitert die Symboltabelle um Informationen zu Typen von Variablen und Routinen oder überprüft Ausdrücke unter Einbeziehung der Symboltabelle, ob sie wohlgetypt sind. Je nach den Eigenschaften der Quellsprache muss die Sammlung von Informationen und die Typprüfung auch auf zwei Besucher verteilt werden.

Ein weiterer Besucher kann dann die Synthese des Zielcodes realisieren. Auch dieser besucht dazu die einzelnen Elemente und sammelt die Zielcodefragmente in seinem lokalen Zustand. Abhängig von der Klasse des besuchten Elements kann er dann bereits gesammelte Fragmente zu größeren kombinieren.

Weitere Besucher können Debuginformationen sammeln oder Codeoptimierungen auf Quellcodebasis durchführen. Alle Besucher können dabei auf die Besuchsfunktionen des allgemeinen Besuchers zurückgreifen, wenn ein Element ohne weitere Operationen nur traversiert werden soll. Auch der Zielcode kann zunächst wiederum in einer Baumstruktur erzeugt werden, um dann verschiedene Optimierungen in unterschiedlichen Besuchern zu realisieren.