Podcast Ch08-12 ♦ Title : Visitor Design Pattern ♦ Description : Motivation; an example; class structure; implementation issues ♦ Participants : Barry Kurtz (instructor); Brandon Winters, Sara Hyde, Cheng Vue, Dan Baehr (students) ♦ Textbook : Object-Oriented Software Engineering: Using UML, Patterns and Java by Bernd Bruegge and Allen H. Dutoit Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 1 A Pattern Taxonomy Pattern Creational Behavioral Structural Pattern Pattern Pattern Composite Singleton Iterator Decorator Abstract Factory Visitor Adapter Builder Command Bridge Observer Factory Prototype Façade Template Proxy Strategy Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 2 the basics ♦ ♦ Intent Intent: Represent an operation to be performed on the elements of an object structure. ♦ Visitor lets you define a new operation without changing the classes of the elements on which it operates ♦ ♦ aka aka: none! These slides were borrowed from lecture notes on Design Patterns by Brian Malloy at Clemson University Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 3 1
Motivation ♦ Consider a compiler that represents programs as Abstract Syntax Trees (ASTs) ♦ need to perform operations on ASTs � type checking � code generation � printing ♦ One option: place all of these operations in the nodes of the AST Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 4 Node class hierarchy Node typeCheck() generateCode(); prettyPrint(); VariableRefNode AssignmentNode typeCheck() typeCheck() generateCode(); generateCode(); prettyPrint(); prettyPrint(); Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 5 Problem with Node class hierarchy ♦ Distributing operations across Node classes leads to a system that’s hard to understand, maintain and change. ♦ it’s confusing to have type-checking code in the same class with code to perform pretty printing. ♦ also, adding a new operation, e.g. data flow analysis, requires recompiling all of the classes! Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 6 2
Visitor ♦ allows us to separate Node classes from operations “on” Node classes ♦ allows each new operation to be added separately, without changing Node class! Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 7 Nodes “accept” visitors Node program accept(NodeVisitor) v.visitAssignment(this) VariableRefNode AssignmentNode accept(NodeVisitor) accept(NodeVisitor v) Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 8 Visitor for Nodes NodeVisitor visitAssignment(node); visitVariableRef(node); VariableRefNode AssignmentNode visitAssignment(node); visitAssignment(node) visitVariableRef(node); visitVariableRef(node) Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 9 3
Visitor Pattern ♦ Define two two class hierarchies � one for elements being operated on (nodes) � one for visitors that define operations on the elements ♦ create new operations by adding a new subclass to Visitor class hierarchy Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 10 Structure of Visitor Pattern Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 11 Collaborations Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 12 4
Circularity ♦ inherent in Visitor pattern: Visitor needs elements & elements need Visitor ♦ emanates from double dispatch ♦ In Java, it’s much easier, don’t have to worry about forward references, or quick compiles ♦ C++ strives for efficiency, at a cost in programmer expertise Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 13 Single Dispatching ♦ Two criteria determine the operation: � name of the request � type of the receiver � Example: calling node->generateCode() on an assignment Node will dynamically bind to the generateCode() function in AssignmentNode Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 14 Double Dispatch ♦ operation that gets executed depends on � kind of request � types of two receivers � example: accept() is double dispatched operation. Its meaning depends on two types: Visitor’s and Element’s Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 15 5
More implementation issues ♦ A visitor must visit each element of the structure ♦ Who is responsible for traversing the structure? � object structure -- most often � an iterator � the visitor -- problem: you will likely dupe traversal code in each concrete visitor Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 16 Accumulating State ♦ Visitors can accumulate state as they traverse ♦ without a visitor, this state information might have to be passed during traversal Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 17 Consequences ♦ Easy to add new operations ♦ Visitor gathers related operations and separates unrelated operations ♦ Adding new ConcreteElement classes takes extra work -- need new abstract operation on Visitor Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 18 6
Recommend
More recommend