An object-oriented programming method called the Visitor design pattern makes it possible to add new operations to preexisting classes without changing them. It improves the modularity and maintainability of code, which makes it perfect for operations on a variety of object structures. Its advantages, and real-world applications are examined in this article.
What is Visitor Design Pattern?
The Visitor design pattern is a behavioral pattern that allows you to add new operations to a group of related classes without modifying their structures. It is particularly useful when you have a stable set of classes but need to perform various operations on them, making it easy to extend functionality without altering the existing codebase.
Real-World Example of Visitor Design Pattern
A simple example of the Visitor design pattern is in an online shopping cart. Imagine you have different items like books, electronics, and clothing. Each item can accept a visitor that performs actions like calculating the total price or applying discounts. This way, you can add new features without changing the item classes, making the system easier to maintain and update.
UML Class Diagram of Visitor design pattern

Components of Visitor Design Pattern
The Visitor design pattern consists of several key components that work together to enable its functionality. Here’s a breakdown of these components:
- Visitor Interface: This interface declares a visit method for each type of element in the object structure. Each method is designed to handle a specific element type.
- Concrete Visitor: This class implements the Visitor interface and provides the specific behavior for each visit method. It contains the logic for the operations that need to be performed on the elements.
- Element Interface: This interface defines an
accept
method that takes a visitor as an argument. This method allows the visitor to visit the concrete elements. - Concrete Elements: These classes implement the Element interface and represent the various types of objects in the structure. Each concrete element defines how it accepts a visitor by calling the corresponding method on the visitor.
- Object Structure: This is the collection of elements (the concrete elements) that the visitor will operate on. It often includes methods to add, remove, and retrieve elements.
How to Implement Visitor Design Pattern?
The Visitor design pattern works by separating an algorithm from the objects on which it operates, allowing you to add new operations without changing the existing object structures. Below is how it functions:
- Step 1: First, you define an interface for the elements (objects) that will accept visitors. This interface usually includes a method for accepting a visitor.
- Step 2: Then, you create concrete classes that implement the element interface. Each class represents an object in your structure and includes the method to accept a visitor.
- Step 3: Next, you define a visitor interface that declares a visit method for each concrete element type. This method will be called when a visitor visits a specific element.
- Step 4: You implement one or more concrete visitor classes, each providing specific operations for the various element types. Each visit method contains the logic for what to do when visiting that element.
- Step 5: When a visitor is applied to an element, the element calls the appropriate visit method on the visitor, passing itself as an argument. This allows the visitor to operate on the element and perform the desired actions.
Example of Visitor Design Pattern
Below is the problem statement to understand visitor design pattern:
Assume a situation whereby you have a set of shapes like circles, squares, and triangles. You want to find the area of each given figure. One option is to add a method that calculates the area of each shape class. Yet, it breaks the open-closed principle, as modifying existing classes is mandatory whenever a new operation emerges.
There are the following steps for implementing Visitor Design Method:
Step 1: Define the Visitor interface:
Java
public interface ShapeVisitor {
void visit(Circle circle);
void visit(Square square);
void visit(Triangle triangle);
}
Step 2: Define the Element interface:
Java
public interface Shape {
void accept(ShapeVisitor visitor);
}
Step 3: Implement Concrete Elements:
Java
public class Circle implements Shape {
// Circle specific properties and methods
@Override
public void accept(ShapeVisitor visitor) {
visitor.visit(this);
}
}
class Square implements Shape {
@Override
public void accept(ShapeVisitor visitor) {
visitor.visit(this);
}
}
class Triangle implements Shape {
@Override
public void accept(ShapeVisitor visitor) {
visitor.visit(this);
}
}
Step 4: Implement Concrete Visitors:
Java
public class AreaCalculator implements ShapeVisitor {
double totalArea = 0;
@Override
public void visit(Circle circle) {
// Calculate area of circle and update totalArea
totalArea += Math.PI * Math.pow(radiusOfCircle, 2);
}
@Override
public void visit(Square square) {
// Calculate area of square and update totalArea
totalArea += Math.pow(sideOfSquare, 2);
}
@Override
public void visit(Triangle triangle) {
// Calculate area of triangle and update totalArea
totalArea += (baseOfTriangle * heightOfTriangle) / 2;
}
public double getTotalArea() {
return totalArea;
}
}
Complete Code of Visitor Design Pattern
Below is the overall code of the above example:
Java
import java.util.ArrayList;
import java.util.List;
// Visitor interface
interface ShapeVisitor {
void visit(Circle circle);
void visit(Square square);
void visit(Triangle triangle);
}
// Element interface
interface Shape {
void accept(ShapeVisitor visitor);
}
// Concrete Elements
class Circle implements Shape {
@Override
public void accept(ShapeVisitor visitor) {
visitor.visit(this);
}
}
class Square implements Shape {
@Override
public void accept(ShapeVisitor visitor) {
visitor.visit(this);
}
}
class Triangle implements Shape {
@Override
public void accept(ShapeVisitor visitor) {
visitor.visit(this);
}
}
// Concrete Visitors
class AreaCalculator implements ShapeVisitor {
private double totalArea = 0;
double radiusOfCircle = 5;
double sideOfSquare = 4;
double baseOfTriangle = 3;
double heightOfTriangle = 6;
@Override
public void visit(Circle circle) {
// Calculate area of circle and update totalArea
totalArea += Math.PI * Math.pow(radiusOfCircle, 2);
}
@Override
public void visit(Square square) {
// Calculate area of square and update totalArea
totalArea += Math.pow(sideOfSquare, 2);
}
@Override
public void visit(Triangle triangle) {
// Calculate area of triangle and update totalArea
totalArea += (baseOfTriangle * heightOfTriangle) / 2;
}
public double getTotalArea() {
return totalArea;
}
}
// Main class
public class Main {
public static void main(String[] args) {
List<Shape> shapes = new ArrayList<>();
shapes.add(new Circle());
shapes.add(new Square());
shapes.add(new Triangle());
AreaCalculator areaCalculator = new AreaCalculator();
for (Shape shape : shapes) {
shape.accept(areaCalculator);
}
System.out.println("Total area: " + areaCalculator.getTotalArea());
}
}
Output
Pros of Visitor Design Pattern
Below are the Pros of Visitor Design Pattern:
- Separation of Concerns: This pattern keeps operations separate from the objects themselves, making it easier to manage and understand the code.
- Easy to Add New Features: You can introduce new operations simply by creating new visitor classes without changing the existing objects. This makes the system flexible.
- Centralized Logic: All the operations are in one place (the visitor), which helps you see how different tasks interact with your objects.
- Easier Maintenance: If you need to update or fix something, you can do it in the visitor class without touching the object classes, making maintenance simpler.
- Type Safety: Each visitor method is specific to an object type, which helps catch errors early and ensures the right operations are applied.
Cons of Visitor Design Pattern
Below are the Pros of Visitor Design Pattern:
- Added Complexity: It can make your code more complicated, especially if you have many types of objects or operations to manage.
- Challenging to Add New Objects: While adding new operations is easy, introducing new types of objects requires changes to all visitor classes, which can be a hassle.
- Tight Coupling: Visitors need to know about all the specific object types, which can create a dependency and make your design less flexible.
- More Classes to Manage: This pattern can lead to a lot of extra classes and interfaces, which can clutter your codebase and make it harder to navigate.
- Not Ideal for Frequent Changes: If your object types change often, the Visitor pattern can become a burden, as you'd need to update multiple visitor classes each time.
Similar Reads
Software Design Patterns Tutorial Software design patterns are important tools developers, providing proven solutions to common problems encountered during software development. This article will act as tutorial to help you understand the concept of design patterns. Developers can create more robust, maintainable, and scalable softw
9 min read
Complete Guide to Design Patterns Design patterns help in addressing the recurring issues in software design and provide a shared vocabulary for developers to communicate and collaborate effectively. They have been documented and refined over time by experienced developers and software architects. Important Topics for Guide to Desig
11 min read
Types of Software Design Patterns Designing object-oriented software is hard, and designing reusable object-oriented software is even harder. Christopher Alexander says, "Each pattern describes a problem which occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way th
9 min read
1. Creational Design Patterns
Creational Design Patterns Creational Design Patterns focus on the process of object creation or problems related to object creation. They help in making a system independent of how its objects are created, composed, and represented. Creational patterns give a lot of flexibility in what gets created, who creates it, and how i
4 min read
Types of Creational Patterns
2. Structural Design Patterns
Structural Design Patterns Structural Design Patterns are solutions in software design that focus on how classes and objects are organized to form larger, functional structures. These patterns help developers simplify relationships between objects, making code more efficient, flexible, and easy to maintain. By using structura
7 min read
Types of Structural Patterns
Adapter Design PatternOne structural design pattern that enables the usage of an existing class's interface as an additional interface is the adapter design pattern. To make two incompatible interfaces function together, it serves as a bridge. This pattern involves a single class, the adapter, responsible for joining fun
8 min read
Bridge Design PatternThe Bridge design pattern allows you to separate the abstraction from the implementation. It is a structural design pattern. There are 2 parts in Bridge design pattern : AbstractionImplementationThis is a design mechanism that encapsulates an implementation class inside of an interface class. The br
4 min read
Composite Method | Software Design PatternComposite Pattern is a structural design pattern that allows you to compose objects into tree structures to represent part-whole hierarchies. The main idea behind the Composite Pattern is to build a tree structure of objects, where individual objects and composite objects share a common interface. T
9 min read
Decorator Design PatternThe Decorator Design Pattern is a structural design pattern that allows behavior to be added to individual objects dynamically, without affecting the behavior of other objects from the same class. It involves creating a set of decorator classes that are used to wrap concrete components.Important Top
9 min read
Facade Method Design PatternFacade Method Design Pattern is a part of the Gang of Four design patterns and it is categorized under Structural design patterns. Before we go into the details, visualize a structure. The house is the facade, it is visible to the outside world, but beneath it is a working system of pipes, cables, a
8 min read
Flyweight Design PatternThe Flyweight design pattern is a structural pattern that optimizes memory usage by sharing a common state among multiple objects. It aims to reduce the number of objects created and to decrease memory footprint, which is particularly useful when dealing with a large number of similar objects.Flywei
10 min read
Proxy Design PatternThe Proxy Design Pattern a structural design pattern is a way to use a placeholder object to control access to another object. Instead of interacting directly with the main object, the client talks to the proxy, which then manages the interaction. This is useful for things like controlling access, d
9 min read
3. Behvioural Design Patterns