Go 4 Visitor Pattern Presented By Matt Wilson

Go 4 Visitor Pattern Presented By: Matt Wilson

Introduction 4 4 This presentation originated out of casual talk between former WMS “C++ Book Club” (defunct program) developers who wanted to continue to get together on occasion to discuss technical topics. It’s expected that all Senior Software Engineers understand the G 04 Design Patterns well, and thus their occasional review is useful. 2

Introduction 4 4 This Presentation Series was created to not only teach what the patterns are, but explain best-practices of when and why you would want to use them Sources used here included the Gang of 4 Design Patterns Book, Head First Design Patterns book, and many online articles and discussion boards on the topic. 3

Visitor Pattern 4

What-is/Why-use Visitor Pattern? 4 4 Formal definition: “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. ” Or in other words: Visitor Pattern enables you to add Operations* to Classes without changing the Class’ interface. A “Visitor” class encapsulates an Operation (“do. X()”) A Visitor can perform its operation on any object that supports being “visited”. 4 Support for being “visited” is added to a class by inheriting from the Visitable-Element interface. 5

What-is/Why-use Visitor Pattern? 4 4 4 *Operations can be thought of like Methods, but with the following difference: 4 Methods use Single Dispatch: Code that gets called only depends on the dynamic type of one object. 4 Visitor Operations use Double Dispatch: Code that gets called depends on the dynamic type of two objects, the Visitor and the object being visited. Visitor is a useful pattern to use when you want to perform operations across a structure of objects. Visitor is a useful pattern to use when working in Graphical GUI systems, where you don’t know what the object types are. 6

Visitor Pattern – UML 7

Visitor Pattern – UML 8

Visitor Pattern – example (Java) //Element interface public interface Visitable { public void accept(Visitor visitor); } //concrete element public class Book implements Visitable { private double price; private double weight; } } //accept the visitor public void accept(Visitor vistor) { visitor. visit(this); // Second Dispatch Here public double get. Price() { return price; } public double get. Weight() { return weight; } 9

Visitor Pattern – example (Java) public interface Visitor { public void visit(Book book); } //visit other concrete items public void visit(CD cd); public void visit(DVD dvd); public class Postage. Visitor implements Visitor { private double total. Postage. For. Cart; //collect data about the book public void visit(Book book) { //assume we have a calculation here related to weight and price //free postage for a book over 10 if(book. get. Price() < 10. 0) { total. Postage. For. Cart += book. get. Weight() * 2; } } //add visitor methods for every other concrete class that the Visitor need to support public void visit(CD cd){. . . } public void visit(DVD dvd){. . . } } //return the internal state public double get. Total. Postage() { return total. Postage. For. Cart; } 1

Visitor Pattern – example (Java) // Our main program public class Shopping. Cart { //normal shopping cart stuff private Array. List<Visitable> items; public double calculate. Postage() { //create a visitor Postage. Visitor visitor = new Postage. Visitor(); //iterate through all items for(Visitable item: items) { item. accept(visitor); // First Dispatch Here } double postage = visitor. get. Total. Postage(); return postage; } } 1

Visitor Pattern – Type Switching done better? 4 Other uses: Visitor Pattern can be useful for encapsulating fragile type-switching code: 4 Example, instead of this: 4 If (X is type. A) { do. A } else if (X is type. B) { do B() }… 4 You can do this: 4 X. accept(visitor); 4 The visitor encapsulates the appropriate operations (do. A, do. B, etc. ) based on what Type of Object X is. 1

Visitor Pattern – Type Switching done better? 4 Note: Switching on Type is a Code Smell that might get flagged in a Code Review. Remember that your classes shouldn’t have references to Concrete Classes to begin with, according to one of the five SOLID Principles of OO Design. 4 Before implementing Visitor to replace the if-else logic, the design should be examined to see if it type switching can be avoided entirely. 1

Visitor Pattern – If-Else 4 It was noted in the presentation on Strategy/State Patterns that they are also effective at removing if-else logic, however the differences are: 4 In Visitor Pattern, the removal is achieved by replacing if/else-type-switching with the Visitor’s double dispatch mechanism. 4 In Strategy/State Patterns, the removal is made by single dispatch via a call to the current Strategy or State, and is not based on type-switching. 1

Visitor Pattern Tradeoffs 4 4 Upsides: 4 A Visitor is highly cohesive, as it is only responsible to perform a single operation. 4 We can create as many Visitors as we want without changing underlying structure. Downside: 4 Visitors are highly coupled to the elements they visit because they need to reference every type they have to visit. 4 If the object hierarchy it has to visit changes, then ALL visitors need to change. 4 Guideline: Use Visitor when the visited object 1

When to use the Visitor Pattern 4 Use the Visitor Pattern when: 4 You want to add functions to class libraries that you don’t have access to the Source Code. 4 You want to recover type information without doing a dynamic cast. 4 You want to apply an operation over a Composite Pattern, because Visitors can traverse a Composite. 4 You want to apply an operation to a bunch of unrelated objects, thus avoiding the need to implement Proxy Pattern. 4 You want to encapsulate operations into single classes, rather than change your derived classes to add these operations. 1

Visitor Pattern Questions ? 17
- Slides: 17