Open In App

Visitor Design Pattern in Java

The Visitor Design Pattern is a behavioral design pattern that allows you to separate algorithms or operations from the objects on which they operate. It enables you to add new operations to objects without modifying their structure.

Visitor-Design-Pattern--(1)

What is the Visitor Design Pattern?

The Visitor Design Pattern is a behavioral design pattern that enables the separation of algorithms or operations from the objects they operate on. It allows you to define new operations on a collection of objects without modifying their classes directly. In essence, the Visitor pattern facilitates adding new behaviors or operations to an object structure by encapsulating them in separate visitor objects, thereby promoting extensibility and flexibility in the design.

Real-Life Example of the Visitor Design Pattern

Imagine you own a zoo with different types of animals: lions, monkeys, and elephants. Now, you want to perform various tasks on these animals, such as feeding, cleaning, and monitoring their health.

Instead of modifying each animal's class to accommodate these tasks, you can implement the Visitor pattern:

Here's how it works:

By using the Visitor pattern in this scenario, you can add new types of tasks or visitors to the zoo without changing the existing animal classes. This makes it easier to manage and extend the zoo's functionality over time.

Key Components in the Visitor Design Pattern

1. Visitor Interface

2. Element Interface

3. Concrete Visitors

4. Concrete Element

UML Class Diagram of the Visitor Design Pattern

Class-Diagram-of-Visitor-Design-Pattern--(1)

Example of the 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:

public interface ShapeVisitor {
    void visit(Circle circle);
    void visit(Square square);
    void visit(Triangle triangle);
}

Step 2: Define the Element interface:

public interface Shape {
    void accept(ShapeVisitor visitor);
}

Step 3: Implement Concrete Elements:

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:

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:

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());
    }
}
Total area: 103.53981

Use Cases of the Visitor Design Pattern

Below are the use cases of visitor design pattern:

Advantages of the Visitor Design Pattern

Below are the advantages of visitor design pattern:

Disadvantage of the Visitor Design Pattern

Below are the disadvantages of visitor design pattern:



Article Tags :