Visitor Design Pattern in Java

Kaan Aydemir Iu
2 min readApr 9, 2023

--

Visitor design pattern is a behavioral design pattern in Java that allows you to separate algorithms from the objects they operate on. This pattern is used when you want to add new operations to an object structure without modifying the objects themselves.

To understand the Visitor design pattern, let’s take an example of a collection of different shapes such as circles, squares, and triangles. Suppose we want to calculate the area of each shape but we don’t want to modify the shape classes themselves.

To accomplish this, we can create an interface called Shape and define a method called accept that takes a Visitor as a parameter. We also create Concrete Elements for each shape, such as Circle, Square, and Triangle, that implement the Shape interface.

public interface Shape {
void accept(ShapeVisitor visitor);
}
public class Circle implements Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
public double getRadius() {
return radius;
}
@Override
public void accept(ShapeVisitor visitor) {
visitor.visit(this);
}
}
public class Square implements Shape {
private double side;
public Square(double side) {
this.side = side;
}
public double getSide() {
return side;
}
@Override
public void accept(ShapeVisitor visitor) {
visitor.visit(this);
}
}
public class Triangle implements Shape {
private double base;
private double height;
public Triangle(double base, double height) {
this.base = base;
this.height = height;
}
public double getBase() {
return base;
}
public double getHeight() {
return height;
}
@Override
public void accept(ShapeVisitor visitor) {
visitor.visit(this);
}
}

Now we create a Visitor interface called ShapeVisitor and define methods for each shape type. For example, we might define a method called visitCircle for calculating the area of a circle.

public interface ShapeVisitor {
void visit(Circle circle);
void visit(Square square);
void visit(Triangle triangle);
}
public class AreaCalculator implements ShapeVisitor {
private double totalArea = 0;
@Override
public void visit(Circle circle) {
totalArea += Math.PI * circle.getRadius() * circle.getRadius();
}
@Override
public void visit(Square square) {
totalArea += square.getSide() * square.getSide();
}
@Override
public void visit(Triangle triangle) {
totalArea += 0.5 * triangle.getBase() * triangle.getHeight();
}
public double getTotalArea() {
return totalArea;
}
}

Finally, we create an Object Structure that contains the different shapes by adding them to a list. We then call the accept method on each shape, passing in the AreaCalculator Visitor.

public class ObjectStructure {
private List<Shape> shapes = new ArrayList<>();
public void addShape(Shape shape) {
shapes.add(shape);
}
public void calculateArea(AreaCalculator areaCalculator) {
for (Shape shape : shapes) {
shape.accept(areaCalculator);
}
}
}
public class Main {
public static void main(String[] args) {
ObjectStructure objectStructure = new ObjectStructure();
objectStructure.addShape(new Circle(5));
objectStructure.addShape(new Square(4));
objectStructure.addShape(new Triangle(3, 6));
AreaCalculator areaCalculator = new AreaCalculator();
objectStructure.calculateArea(areaCalculator);
System.out.println("Total area: " + areaCalculator.getTotalArea());
}
}

In conclusion, the Visitor design pattern is a powerful tool for separating algorithms from the objects that they operate on. By using this pattern, you can create more flexible and maintainable code that is easier to modify and extend. With the example provided, you can now apply the visitor pattern in your projects to improve software design and create more efficient and effective solutions.

--

--