W3C home > Mailing lists > Public > www-dom@w3.org > July to September 1998

Re: latest DOM spec 19980720

From: Michael Allen <Michael.R.Allen@Eng.Sun.COM>
Date: Tue, 21 Jul 1998 16:47:50 -0700 (PDT)
Message-Id: <199807212347.QAA26666@doppio.eng.sun.com>
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 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Friday, 22 June 2012 06:13:45 GMT