Skip to main content

How does Visitor help add new operations without modifying classes?

The Visitor pattern lets you add new operations on objects without changing their classes, because all the logic of the new actions is moved into an external object, the visitor.


1. The Problem Without Visitor

Suppose there are several types of elements:

java
class Circle { void draw() { ... } } class Square { void draw() { ... } }

Now you need to add new operations:

  • exporting to PDF,
  • calculating area,
  • validating parameters.

Without Visitor, you'd have to add new methods to every class:

java
class Circle { void draw() { ... } void exportToPDF() { ... } // added void calculateArea() { ... } // added }

The problems:

  • existing classes have to be edited every time;
  • with dozens of operations and elements, the code grows quickly;
  • the Open/Closed principle is violated (classes are open to modification).

2. How Visitor Solves This

Visitor moves all the "actions" out of the classes themselves and into external objects, visitors. Now every new algorithm is created as a new class, instead of new methods inside the elements.


3. Structure

java
interface Shape { void accept(ShapeVisitor visitor); } interface ShapeVisitor { void visit(Circle c); void visit(Square s); } class Circle implements Shape { public void accept(ShapeVisitor visitor) { visitor.visit(this); } } class Square implements Shape { public void accept(ShapeVisitor visitor) { visitor.visit(this); } }

4. Adding New Operations

To add, for example, exporting to PDF, you just need to create a new visitor:

java
class ExportToPDFVisitor implements ShapeVisitor { public void visit(Circle c) { System.out.println("Exporting a circle to PDF"); } public void visit(Square s) { System.out.println("Exporting a square to PDF"); } }

For another operation (for example, calculating area), a different visitor:

java
class AreaCalculationVisitor implements ShapeVisitor { public void visit(Circle c) { System.out.println("Calculating the circle's area"); } public void visit(Square s) { System.out.println("Calculating the square's area"); } }

The elements (Circle, Square) stay the same, they just "accept" the visitor.


5. Usage

java
List<Shape> shapes = List.of(new Circle(), new Square()); // Add any new operation without changing the Shape classes ShapeVisitor exportVisitor = new ExportToPDFVisitor(); ShapeVisitor areaVisitor = new AreaCalculationVisitor(); for (Shape shape : shapes) { shape.accept(exportVisitor); shape.accept(areaVisitor); }

6. Why This Works

  • The elements only know how to accept a visitor (accept()), but don't know what it does with them.
  • The visitor implements all the specific operations for each element type.
  • Adding a new operation = a new Visitor, without touching Shape, Circle, Square.

7. The Principle Being Implemented

Visitor embodies the Open/Closed principle:

The element classes are closed for modification, but open for extension through new visitors.


Conclusion

Visitor lets you add new operations without changing the classes of the objects themselves, because:

  1. All the logic of the new actions is moved into external classes (visitors).
  2. The elements only provide an entry point, the accept() method.
  3. Adding new behavior = creating a new visitor, not changing existing classes.

Summary:

Visitor moves changes from inside classes into an external behavior layer, keeping the structure stable and the system flexible.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.