Betrachten Sie den folgenden Besucher für einen einfachen Sprachinterpreter.
%Vor%Der Vollständigkeit halber füge ich einen Code hinzu, der die notwendigen Implementierungsdetails enthält (Sie können die Frage überspringen und direkt lesen).
%Vor%Eine var-Anweisung ist wie folgt definiert:
%Vor%eine gültige Sprachinstanz
%Vor% Eine abstrakte Möglichkeit, den Knoten VarStat
darzustellen, ist folgender:
Die Frage
Die übliche VisitorPattern-Anwendung wäre
%Vor% Da ich aber weiß, dass "Ident" vom Typ Ident
ist, ist eine mögliche Optimierung
Das würde 2 Methodenaufrufe überspringen, was die Leistung verbessert (tatsächlich gibt es in meinem Szenario einen schönen Schub).
Wird das als Konstruktionsfehler angesehen, der zu zukünftigen Problemen führen könnte?
Besucher ist nur ein kompliziertes Gerüst, um Double-Dispatch auf Sprachen wie Java zu implementieren.
Wenn Sie mit Blattarten arbeiten, brauchen Sie keinen Doppelversand; Der Laufzeittyp ist zur Kompilierzeit bekannt. Eine Blattart direkt zu versenden, ist nicht nur eine Optimierung, sie ist mehr aus Prinzip.
Das Problem ist natürlich, dass ein Blatttyp in Zukunft zu einem Super-Typ werden kann. Mit dem heutigen Refactor-Tool in IDEs ist das kein großes Problem.
Es ist besser, ein einfaches Design für die Anforderung der Gegenwart zu erstellen, als ein komplexes Design für unbekannte zukünftige Anforderungen zu erstellen.
In Java 8 können wir Double-Dispatch mit einer Syntax implementieren, die der echten Doppel-Dispatch sehr nahe kommt
%Vor%Siehe auch - Java Class.cast () und Overload
In diesem Fall wäre es kein Besuchermuster. Und es muss nicht sein, wenn es Ihren Anforderungen entspricht, Besucher werden oft missbraucht und führen zu Überarchitektur.
Sie werden jedoch potenzielle Vorteile verlieren. Beispielsweise können Sie keinen Decorator oder Proxy für Ident erstellen und in der Methode accept etwas Zusätzliches ausführen, bevor Sie den Aufruf an das Decorated / Proxy-Objekt weiterleiten.
Könnte es Probleme verursachen? Schwer zu sagen. (Ich denke, es könnte zu Überraschungen führen, wenn sich die Grammatik ändert ...)
Aber ich denke, das eigentliche Problem ist, ob dies eine lohnende Optimierung ist. Konkret: Werden zwei Methodenaufrufe gespeichert, um einen großen Unterschied im Gesamtbild zu machen? Meine Intuition ist, dass es nicht.
Und ist die Leistung dieses Dolmetschers wirklich wichtig?
Und wenn ja, warum verwenden Sie das Besuchermuster im Interpreter? Sollten Sie nicht zu einem zwischenzeitlichen virtuellen Maschinencode kompilieren? Oder zu Bytecodes?
Tags und Links java code-design visitor