behavioral

Visitor

Separate an algorithm from the object structure it operates on by moving behavior into visitor objects.

Problem

behavioral

You need to perform operations across a set of different object types without stuffing all the logic into the objects themselves.

Integration notes

Visitor is useful for AST processing, reporting, cart calculations, and exporting object structures to alternate formats.

Tradeoffs

  • Requires updating the visitor interface when new element types are added
  • Can be awkward if the object structure changes often

Languages

typescript, java, python, angular, react, react-native, csharp, dotnet

Platforms

Web, Backend, Mobile, UI kits, Cross-platform systems

Variants

Scenarios

Shape visitor

Different shapes accept visitors that can render or measure them without changing the shape classes.

Language examples

Core languages

Frameworks and libraries

Shape visitortypescript

The shape visitor computes area across different shape types without moving that logic into the shape classes.

TypeScript
interface ShapeVisitor {
  visitCircle(circle: Circle): void;
  visitRectangle(rectangle: Rectangle): void;
}


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


class Circle implements Shape {
  constructor(public radius: number) {}


  accept(visitor: ShapeVisitor): void {
    visitor.visitCircle(this);
  }
}


class Rectangle implements Shape {
  constructor(
    public width: number,
    public height: number
  ) {}


  accept(visitor: ShapeVisitor): void {
    visitor.visitRectangle(this);
  }
}


class AreaVisitor implements ShapeVisitor {
  public total = 0;


  visitCircle(circle: Circle): void {
    this.total += Math.PI * circle.radius * circle.radius;
  }


  visitRectangle(rectangle: Rectangle): void {
    this.total += rectangle.width * rectangle.height;
  }
}


const shapes: Shape[] = [
  new Circle(3),
  new Rectangle(4, 5)
];


const visitor = new AreaVisitor();
for (const shape of shapes) {
  shape.accept(visitor);
}


console.log(visitor.total);

Real-world examples

  • AST traversal: Compilers and linters often traverse syntax trees with visitors to gather information or transform nodes.
  • Cart calculations: Shopping systems may compute totals, taxes, and promotions across mixed item types.
  • Export formats: Documents and diagrams can be exported to multiple formats without changing the element classes.