Your Guide to Design Patterns – Visitor Pattern (Part 1)

Design Patterns - The Visitor Pattern

This week we’ll look at the last behavioural design pattern, the Visitor pattern.

The Gang of Four book defines the Visitor pattern as:

“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.”

The Visitor pattern allows us to separate algorithms from the objects on which they operate.

Explanation

We usually extend the behaviour of a class hierarchy by adding additional methods for the behaviour we need.

Occasionally the additional behaviours are not consistent with the design of the existing class model. Depending on how we have designed the class hierarchy, it may be impossible to extend the behaviours without modifying many or all of the classes. Other times we don’t have enough information about the future required behaviours to accommodate them in our design.

By using the Visitor pattern, we can support the possibility of adding behaviours of the class hierarchy at some time in the future. By separating the algorithm from the data it works on, the pattern allows us to define new operations without changing the classes in the hierarchy.

The Visitor pattern implements double dispatch. Usually when we invoke a method, we use single dispatch. The method name and the target object type determines which method gets invoked. In double dispatch, the method that gets invoked depends on the method name and the types of two objects: the type of the visitor and the type of the element it visits.

Double dispatch in the Visitor pattern works by having two different abstract/interface types each having a method that takes a parameter of the other type. One type calls the method of the other type, and that method executes the desired strategy on the first type.

Participants

The participants of the Visitor pattern are the following:

  • Element: an interface that contains an accept() method that takes a Visitor as an argument.
  • ConcreteElement: implements the accept() method defined in Element.
  • Visitor: an interface that declares a visit() method for each class of ConcreteElement in the object structure.
  • ConcreteVisitor: the concrete classes that appropriately implement each method declared by the Visitor interface.

We follow these steps to implement the Visitor pattern:

  • We add an accept(Visitor) method to the Element hierarchy.
  • We create a Visitor base class/interface with a visit() method for every element type.
  • We create concrete derived classes, appropriately implementing each method in the Visitor base class/interface .
  • The client code creates visitor objects and passes each object to the accept() calls.

Simple Implementation Code

Let’s first create the Element interface with an accept() method that takes a Visitor as an argument:

public interface Element {
   void accept(Visitor v);
}

Next we implement three concrete classes implementing the Element interface. Here we’ll use class names from the Hickory, Dickory, Dock limerick. Only the first class is shown; the others are identical except in name.

public class Hickory implements Element {
   public void accept(Visitor v) {
      v.visit(this);
   }
   @Override
   public String toString() {
      return "Hickory";
   }
}

Next we define the Visitor interface:

interface Visitor {
   void visit(Hickory hickory);
   void visit(Dickory dickory);
   void visit(Dock dock);
}

Now let’s create two concrete implementations of the Visitor interface, UpVisitor and DownVisitor. Again only one is shown; the other is identical except for running down the clock.

class UpVisitor implements Visitor {
   public void visit(Hickory hickory) {
      System.out.println(hickory + " runs up the clock.");
   }

   public void visit(Dickory dickory) {
      System.out.println(dickory + " runs up the clock.");
   }

   public void visit(Dock dock) {
      System.out.println(dock + " runs up the clock.");
   }
}

Finally we create the client code that creates visitor objects and passes each object to the accept() methods.

public class VisitorClient {

   public static void main(String args[]) {

      Element list[] = {new Hickory(), new Dickory(), new Dock()};

      UpVisitor up = new UpVisitor();
      DownVisitor down = new DownVisitor();

      for (Element element : list) 
         element.accept(up);

      for (Element element : list) 
         element.accept(down);

   }
}

Design Example

We’ll continue the Visitor pattern next week where we’ll look at a longer example from our first person shooter game.

Stay tuned!

As always, please share your comments and questions.

Leave a Comment

Your email address will not be published. Required fields are marked *

Code like a Java Guru!

Thank You

We're Excited!

Thank you for completing the form. We're excited that you have chosen to contact us about training. We will process the information as soon as we can, and we will do our best to contact you within 1 working day. (Please note that our offices are closed over weekends and public holidays.)

Don't Worry

Our privacy policy ensures your data is safe: Incus Data does not sell or otherwise distribute email addresses. We will not divulge your personal information to anyone unless specifically authorised by you.

If you need any further information, please contact us on tel: (27) 12-666-2020 or email info@incusdata.com

How can we help you?

Let us contact you about your training requirements. Just fill in a few details, and we’ll get right back to you.

Your Java tip is on its way!

Check that incusdata.com is an approved sender, so that your Java tips don’t land up in the spam folder.

Our privacy policy means your data is safe. You can unsubscribe from these tips at any time.