Visitor

Visitor

Der Besucher (engl. visitor oder visitor pattern) ist ein Entwurfsmuster aus dem Bereich der Softwareentwicklung und 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. Das Muster ist eines der sogenannten GoF-Muster (siehe Viererbande).

Inhaltsverzeichnis

Verwendung

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 aus. 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 Objektstruktur verteilt arbeitet, aber zentral verwaltet werden soll.

UML-Diagramm

UML-Diagramm des Entwurfsmusters "Visitor"

Akteure

  • Besucher
    • deklariert für jede Klasse konkreter Elemente 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
    • deklariert eine Schnittstelle zum Empfang eines Besuchers
  • KonkretesElement
    • implementiert den Empfang eines Besuchers
  • ObjektStruktur

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

  • 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 viele Besucher-besuche-Methoden implementiert werden müssen.

Beispiele

Virtuelles Reisebüro

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 Übersetzern (Compiler)

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

Codebeispiele

Java

Das folgende Codebeispiel ist in der Programmiersprache Java verfasst:

interface Visitor {
    void visit(Wheel wheel);
    void visit(Engine engine);
    void visit(Body body);
    void visit(Car car);
}
interface CarElement{
    public void accept(Visitor visitor);
}
class Wheel implements CarElement{
    private String name;
    Wheel(String name) {
        this.name = name;
    }
    String getName() {
        return this.name;
    }
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}
 
class Engine implements CarElement{
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}
 
class Body implements CarElement{
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}
 
class Car {
    CarElement[] elements;
    public CarElement [] getElements(){
        return elements.clone();
    }
    public Car() {
        this.elements = new CarElement[]
          { new Wheel("front left"), new Wheel("front right"),
            new Wheel("back left") , new Wheel("back right"),
            new Body(), new Engine()};
    }
}
 
class PrintVisitor implements Visitor {
 
    public void visit(Wheel wheel) {      
        System.out.println("Visiting "+ wheel.getName()
                            + " wheel");
    }
    public void visit(Engine engine) {
        System.out.println("Visiting engine");
    }
    public void visit(Body body) {
        System.out.println("Visiting body");
    }
 
    public void visit(Car car) {
        System.out.println("\nVisiting car");
        for(CarElement element : car.getElements()) {
            element.accept(this);
        }
        System.out.println("Visited car");
    }
 
}
 
class DoVisitor implements Visitor {
    public void visit(Wheel wheel) {
        System.out.println("Steering my wheel");
    }
    public void visit(Engine engine) {
        System.out.println("Starting my engine");
    }
    public void visit(Body body) {
        System.out.println("Moving my body");
    }
    public void visit(Car car) {
        System.out.println("\nStarting my car");
        for(CarElement carElement : car.getElements()) {
            carElement.accept(this);
        }
        System.out.println("Started car");
    }
 
}
 
public class VisitorDemo {
    public static void main(String[] args){
        Car car = new Car();
        Visitor printVisitor = new PrintVisitor();
        Visitor doVisitor = new DoVisitor();
        printVisitor.visit(car);
        doVisitor.visit(car);
    }
}

Man beachte, dass die accept-Methode tatsächlich in jeder Element-Klasse implementiert werden muss, damit der Compiler die richtige überladene visit-Methode auswählen kann.

Verwandte Entwurfsmuster

  • Kommando. Das Command Pattern kapselt wie der Visitor eine oder mehrere Funktionen in einem Objekt, um diese an einen Aufrufer zuzustellen. Im Gegensatz zum Visitor enthält das Command Pattern kein Prinzip zur Traversierung einer Objektstruktur.
  • Iterator. Der Iterator definiert ein Traversierungsprinzip wie auch der Visitor, macht aber keine Typunterscheidung bei den traversierten Objekten.

Beziehung zu anderen Entwurfsmustern

  • Kompositum. Wenn die Typen in einer Kompositstruktur ausreichend stabil definiert sind, bietet sich ein Visitor zur Bearbeitung der Struktur an.

Weblinks


Wikimedia Foundation.

Игры ⚽ Поможем решить контрольную работу

Schlagen Sie auch in anderen Wörterbüchern nach:

  • visitor — visitor, visitant, guest, caller mean one who visits another or comes to pay a visit. Visitor is the general word applicable to anyone who comes under this description {there are visitors in the drawing room} {summer visitors} but it is… …   New Dictionary of Synonyms

  • Visitor — Géographie Altitude 2 211 m Massif Alpes dinariques Longueur 12&# …   Wikipédia en Français

  • Visitor Q — Données clés Titre original Bizita Q Réalisation Takashi Miike Scénario Itaru Era Acteurs principaux Kenichi Endo Shungicu Uchida Kazushi Watanabe Pays d’origine …   Wikipédia en Français

  • Visitor — Шаблон Visitor(также известный как Посетитель) – Шаблон проектирования Поведенческий шаблон (Behavioral). Описывает операцию, которая выполняется над объектами других классов. При изменении Visitor нет необходимости изменять обслуживаемые классы …   Википедия

  • visitor — [viz′it ər] n. [ME visitour < Anglo Fr < MFr visiteur] a person making a visit SYN. VISITOR is the general term for one who comes to see a person or spend some time in a place, whether for social, business, or professional reasons, or for… …   English World dictionary

  • Visitor — Vis it*or [Cf. F. visiteur.] [Written also {visiter}.] 1. One who visits; one who comes or goes to see another, as in civility or friendship. This great flood of visitors. Shak. [1913 Webster] 2. A superior, or a person lawfully appointed for the …   The Collaborative International Dictionary of English

  • visitor — a person seeking entry to the UK as a visitor will be admitted if he satisfies the immigration officer that: (1) he is genuinely seeking entry for the period of the visit stated by him; (2) for that period he will maintain and accommodate himself …   Law dictionary

  • visitor — early 15c., from VISIT (Cf. visit) + OR (Cf. or). Sports sense is from 1900 …   Etymology dictionary

  • visitor — is spelt or, not er …   Modern English usage

  • visitor — [n] person temporarily in a foreign location caller, company, foreigner, guest, habitué, inspector, invitee, out of towner, transient, visitant; concept 423 Ant. host …   New thesaurus

  • visitor — ► NOUN 1) a person visiting a person or place. 2) a migratory bird present in a locality for only part of the year …   English terms dictionary

Share the article and excerpts

Direct link
Do a right-click on the link above
and select “Copy Link”