Visitor Design Pattern

Get an overview of the visitor design pattern.

Overview

We often have object structures in our programs. For example, we might have objects in an interface that’s implemented by various concrete classes. Sometimes, we want to add functionality to this object structure. We might be tempted to add a method for each additional functionality to the interface. However, this could violate the single responsibility and the open-closed design principles. It isn’t a good idea to modify the interface every time we need to add a functionality to the concrete objects.

Let’s assume that we have a store with different types of products, such as laptops and smartphones. Also, we have different types of customers (such as new customers, gold-level customers, and platinum-level customers). The operation that the code needs to perform is the calculation of the bill for each customer-product pair.

The visitor pattern can solve this problem by creating a separate class, called the Visitor, that contains the algorithm for calculating the bill. This class is then passed to the elements of the object (products and customers).

For example, let’s say we have a class called Product, with subclasses Laptop and Smartphone, and classes NewCustomer, GoldCustomer, and PlatinumCustomer, which represent different types of customers. We would create a class called BillCalculatorVisitor, which will implement the algorithm to calculate the bill. Then, we would add a method called Accept to each product and customer class, which calls the appropriate method in the BillCalculatorVisitor class, passing itself as an argument.

The advantage of this pattern is that if we want to add new types of products or customers, we can do so without changing the BillCalculatorVisitor class and hence following the open-closed principle. Moreover, if we want to change the algorithm for calculating the bill, we can do so without changing the product and customer classes. This makes the code more extendable, flexible, and maintainable.

Definition

The visitor design pattern defines new operations without changing the object structure.

Explanation

In the visitor design pattern, we add a single method named accept(visitor) to the interface defining the object structure. Each concrete class implementing this interface will need to implement this method. Additionally, we define a Visitor interface and implement it through concrete classes, one for each additional functionality we want to implement. In our example, these concrete classes will perform the visit operation on the objects. Likewise, other concrete visitor classes can be defined for other operations. Look at the UML diagram of the visitor design pattern under the “Structure” heading below.

We’ll explain the pattern in greater detail through coding examples in the next lesson.

Type

The visitor design pattern belongs to the behavioral design patterns.

Purpose

The visitor design pattern:

  • Encapsulates an operation executed on an object structure as an object.
  • Allows us to define new operations without changing the object structure.

Applicability

The visitor design pattern is applicable where the operation of the object changes more frequently. With the visitor pattern, we can add operations without changing the structure of the object.

Structure

Get hands-on with 1200+ tech skills courses.