17
Go4 Visitor Pattern Presented By: Matt Wilson

Go4 Visitor Pattern Presented By: Matt Wilson. Introduction 2 This presentation originated out of casual talk between former WMS “C++ Book Club” (defunct

Embed Size (px)

Citation preview

Page 1: Go4 Visitor Pattern Presented By: Matt Wilson. Introduction 2  This presentation originated out of casual talk between former WMS “C++ Book Club” (defunct

Go4 Visitor Pattern

Presented By:Matt Wilson

Page 2: Go4 Visitor Pattern Presented By: Matt Wilson. Introduction 2  This presentation originated out of casual talk between former WMS “C++ Book Club” (defunct

Introduction

2

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 G04 Design Patterns well, and thus their occasional review is useful.

Page 3: Go4 Visitor Pattern Presented By: Matt Wilson. Introduction 2  This presentation originated out of casual talk between former WMS “C++ Book Club” (defunct

Introduction

3

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.

Page 4: Go4 Visitor Pattern Presented By: Matt Wilson. Introduction 2  This presentation originated out of casual talk between former WMS “C++ Book Club” (defunct

Visitor Pattern

4

Page 5: Go4 Visitor Pattern Presented By: Matt Wilson. Introduction 2  This presentation originated out of casual talk between former WMS “C++ Book Club” (defunct

What-is/Why-use Visitor Pattern?

5

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 (“doX()”) A Visitor can perform its operation on any object that supports being

“visited”. Support for being “visited” is added to a class by inheriting

from the Visitable-Element interface.

Page 6: Go4 Visitor Pattern Presented By: Matt Wilson. Introduction 2  This presentation originated out of casual talk between former WMS “C++ Book Club” (defunct

What-is/Why-use Visitor Pattern?

6

*Operations can be thought of like Methods, but with the following difference:

Methods use Single Dispatch: Code that gets called only depends on the dynamic type of one object.

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.

Page 7: Go4 Visitor Pattern Presented By: Matt Wilson. Introduction 2  This presentation originated out of casual talk between former WMS “C++ Book Club” (defunct

Visitor Pattern – UML

7

Page 8: Go4 Visitor Pattern Presented By: Matt Wilson. Introduction 2  This presentation originated out of casual talk between former WMS “C++ Book Club” (defunct

Visitor Pattern – UML

8

Page 9: Go4 Visitor Pattern Presented By: Matt Wilson. Introduction 2  This presentation originated out of casual talk between former WMS “C++ Book Club” (defunct

Visitor Pattern – example (Java)

9

//Element interfacepublic interface Visitable{ public void accept(Visitor visitor);}

//concrete elementpublic 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 getPrice() { return price; } public double getWeight() { return weight; }}

Page 10: Go4 Visitor Pattern Presented By: Matt Wilson. Introduction 2  This presentation originated out of casual talk between former WMS “C++ Book Club” (defunct

Visitor Pattern – example (Java)

10

public interface Visitor{ public void visit(Book book);

//visit other concrete items public void visit(CD cd); public void visit(DVD dvd);  }

public class PostageVisitor implements Visitor{ private double totalPostageForCart;     //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.getPrice() < 10.0) { totalPostageForCart += book.getWeight() * 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 getTotalPostage() { return totalPostageForCart;    }}

Page 11: Go4 Visitor Pattern Presented By: Matt Wilson. Introduction 2  This presentation originated out of casual talk between former WMS “C++ Book Club” (defunct

Visitor Pattern – example (Java)

11

// Our main programpublic class ShoppingCart{ //normal shopping cart stuff private ArrayList<Visitable> items;  public double calculatePostage() { //create a visitor PostageVisitor visitor = new PostageVisitor();

//iterate through all items for(Visitable item: items) { item.accept(visitor); // First Dispatch Here }

double postage = visitor.getTotalPostage(); return postage;  } }

Page 12: Go4 Visitor Pattern Presented By: Matt Wilson. Introduction 2  This presentation originated out of casual talk between former WMS “C++ Book Club” (defunct

Visitor Pattern – Type Switching done better?

12

Other uses: Visitor Pattern can be useful for encapsulating fragile type-switching code:

Example, instead of this: If (X is typeA) { doA } else if (X is typeB) { do B() }…

You can do this: X.accept(visitor);

The visitor encapsulates the appropriate operations(doA, doB, etc.) based on what Type of Object X is.

Page 13: Go4 Visitor Pattern Presented By: Matt Wilson. Introduction 2  This presentation originated out of casual talk between former WMS “C++ Book Club” (defunct

Visitor Pattern – Type Switching done better?

13

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.

Before implementing Visitor to replace the if-else logic, the design should be examined to see if it type switching can be avoided entirely.

Page 14: Go4 Visitor Pattern Presented By: Matt Wilson. Introduction 2  This presentation originated out of casual talk between former WMS “C++ Book Club” (defunct

Visitor Pattern – If-Else

14

It was noted in the presentation on Strategy/State Patterns that they are also effective at removing if-else logic, however the differences are:

In Visitor Pattern, the removal is achieved by replacing if/else-type-switching with the Visitor’s double dispatch mechanism.

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.

Page 15: Go4 Visitor Pattern Presented By: Matt Wilson. Introduction 2  This presentation originated out of casual talk between former WMS “C++ Book Club” (defunct

Visitor Pattern Tradeoffs

15

Upsides: A Visitor is highly cohesive, as it is only responsible to perform

a single operation. We can create as many Visitors as we want without changing

underlying structure.

Downside: Visitors are highly coupled to the elements they visit because

they need to reference every type they have to visit. If the object hierarchy it has to visit changes, then ALL visitors

need to change. Guideline: Use Visitor when the visited object hierarchy isn’t

expected to be extended over time.

Page 16: Go4 Visitor Pattern Presented By: Matt Wilson. Introduction 2  This presentation originated out of casual talk between former WMS “C++ Book Club” (defunct

When to use the Visitor Pattern

16

Use the Visitor Pattern when: You want to add functions to class libraries that you

don’t have access to the Source Code. You want to recover type information without doing

a dynamic cast. You want to apply an operation over a Composite

Pattern, because Visitors can traverse a Composite.

You want to apply an operation to a bunch of unrelated objects, thus avoiding the need to implement Proxy Pattern.

You want to encapsulate operations into single classes, rather than change your derived classes to add these operations.

Page 17: Go4 Visitor Pattern Presented By: Matt Wilson. Introduction 2  This presentation originated out of casual talk between former WMS “C++ Book Club” (defunct

Visitor Pattern Questions ?

17