- From: Michael Allen <Michael.R.Allen@Eng.Sun.COM>
- Date: Tue, 21 Jul 1998 16:47:50 -0700 (PDT)
- To: www-dom@w3.org
With all this talk of quickly casting to subclasses from a base class reference, I wonder if anyone has ever thought of putting Visitor design pattern functionality into Node? I have also heard the Visitor pattern referred to as "double dispatch". It would look something like this (in pseudo-Java): public interface Node { // rest of node methods and stuff public void visit(NodeVisitor v); } public interface NodeVisitor { public void visitNode(Node n); public void visitElement(Element e); public void visitAttribute(Attribute a); public void visitData(Data d); } And then in the actual implementation: public class Foo { public void bar() { // Somehow this thing gets a Node: Node n = getTheNode(); MyNodeVisitor visitor = v; n.visit(v); } } public class MyNodeVisitor implements NodeVisitor { public void visitNode(Node n) { // do the right thing for plain nodes } public void visitElement(Element e) { // do the right thing for elements } public void visitAttribute(Attribute a) { // do the right thing for attributes } public void visitData(Data d) { // do the right thing for data } } public class MyElement extends MyNode implements Element { // ... other element methods ... public void visit(NodeVisitor v) { v.visitElement(this); } } public class MyData extends MyNode implements Data { // ... other data methods ... public void visit(NodeVisitor v) { v.visitNode(this); } } The implementations of Node and the descendants of those implementations each override the visit(NodeVisitor); method and call the appropriate NodeVisitor method, passing themselves in as parameters. This pattern obviates the need for any casting; all the type checking is done by the compiler and any internal type checking mechanisms. To extend this pattern to encompass the HTML specific classes, you just extend the NodeVisitor interface to take more methods. To avoid type checking what kind of NodeVisitor a Node has received, you might make NodeVisitor an abstract base class with an Enumerated type field which contains an int (or bitfield, maybe) which specifies its type. That way, subclasses which the base NodeVisitor doesn't cover could check the type of visitors without doing an instanceof test (which, I believe, does not exist in C++ anyway; however, I could be wrong, it's been a long time since I did any C++ programming) and cast as appropriate. The Visitor pattern really excels at quickly and efficiently digesting structures like the DOM's Node hierarchy, where a program needs to differentiate by their subclasses a tree of objects which all inheret from the same base class. It is far more effcient than instanceof/casting tests with big if-then-else statements, and faster again than checking something like a string which contains the "name" of the subclass in it (up to 8x faster than the latter, according to some tests I ran under JDK1.1.6 on my Solaris box). The only structure that approached it in speed was a switch() statement off of an Enumerated int field in the object. Throwing my hat in the ring, Michael Allen
Received on Tuesday, 21 July 1998 19:47:31 UTC