- From: Tim Taylor <ttaylor@sigma6.com>
- Date: Wed, 04 Aug 1999 17:08:56 -0400
- To: www-dom@w3.org
I am curious if the Visitor design pattern has been considered for inclusion in the DOM2 API? IMO, it is a natural addition. Initially, I questioned the absence of a Visitor interface, then I questioned myself. I briefly, and incorrectly, concluded that Iterator was sufficient. Upon further reflection, though, I realized that Visitor is complementary to Iterator. From "Design Patterns" by the GoF [1]: "Who is responsible for traversing the object structure?...We can put responsibility for traversal in any of three places: the object structure [the DOM], the visitor, or in a separate iterator object..." I considered whether the Filter interface could be used as a substitute despite the semantic distaste of not actually using it for filtering. However, Filter lacks the double-dispatch technique, and "this is the key to the Visitor pattern" [1]. Through double-dispatch and either polymorphism or appropriate method names, the visitor has a visit method invoked for the appropriate Node subclass. Achieving similar results with Filter would require a switch statement or similar conditional on the node type, which is decidedly non-Object-Oriented, followed by casting to a subclass, which is potentially dangerous. Based on these conclusions, I decided that a Visitor interface would be a useful extension to Iterators and Filters. I've included a basic example [3] of what a DOM Visitor interface might look like. I'm sure the WG is aware of IBM's Visitor interface in their TX API as another example. [1] "Design Patterns, Elements of Reusable Object-Oriented Software"; by Erich Gamma, et. al.; Chapter 5, Visitor, Implementation [2] IBM xml4j <uri:http://www.alphaworks.ibm.com/> (sorry, Alphaworks seems to be down at the moment, so I don't have the full URI) [3] Visitor, Java binding example /** interface for visiting nodes of a DOM document */ public interface Visitor { /* multiple visit methods with signatures that only differ by the argument and rely on method overloading (polymorphism?) would be preferable. However, including the type in the method names appears to be more prevalent in the examples I've seen */ public void visitAttr(Attr attr); public void visitCDATASection(CDATASection cdataSection); public void visitComment(Comment comment); public void visitDocument(Document document); public void visitDocumentFragment(DocumentFragment documentFragment); public void visitDocumentType(DocumentType documentType); public void visitElement(Element element); public void visitEntity(Entity entity); public void visitEntityReference(EntityReference entityReference); public void visitNotation(Notation notation); public void visitProcessingInstruction( ProcessingInstruction processingInstruction); public void visitText(Text text); } /* every concrete sub-type of Node must implement an accept method, and call the appropriate visit method for the sub-type. Here's an example for a concrete Element class and a concrete Text class */ public class ConcreteElement implements org.w3c.dom.Element { /* other element methods */ ... /* accept a visitor */ void accept(Visitor visitor) { visitor.visitElement(this); } } public class ConcreteText implements org.w3c.dom.Text { /* other Text methods */ ... /* accept a visitor */ void accept(Visitor visitor) { visitor.visitText(this); } } -- Tim Taylor sigma6 Interactive Media ttaylor@sigma6.com conceive : construct : connect tm
Received on Wednesday, 4 August 1999 17:23:35 UTC