Open In App

Visitor Pattern | JavaScript Design Patterns

The visitor pattern is a behavioral design pattern that allows you to add new behaviors or operations to a set of objects without modifying their structure. It achieves this by separating the algorithm from the objects on which it operates.

Characteristics of the Visitor Pattern in JavaScript Design Patterns

Here are the main features and characteristics of the Visitor pattern:

Explanation of the Visitor Pattern in Javascript

In JavaScript, the Visitor pattern is a design pattern that allows you to add new behaviors or operations to objects of different types without modifying their individual classes. It separates the algorithm from the objects being operated upon. This is particularly useful when dealing with complex data structures or object hierarchies.



Here’s an explanation of the Visitor pattern in JavaScript:

Key Components:

Example of the Visitor Pattern for Shapes in JavaScript

Let’s use an example of different geometric shapes to illustrate the Visitor pattern in JavaScript:




// Visitor Interface
class ShapeVisitor {
  visitCircle(circle) {}
  visitSquare(square) {}
  visitTriangle(triangle) {}
}
// Concrete Visitors
class AreaCalculator extends ShapeVisitor {
  visitCircle(circle) {
    // Calculate and return the area of a circle.
  }
  visitSquare(square) {
    // Calculate and return the area of a square.
  }
 
  visitTriangle(triangle) {
    // Calculate and return the area of a triangle.
  }
}
 
class PerimeterCalculator extends ShapeVisitor {
  visitCircle(circle) {
    // Calculate and return the perimeter of a circle.
  }
 
  visitSquare(square) {
    // Calculate and return the perimeter of a square.
  }
 
  visitTriangle(triangle) {
    // Calculate and return the perimeter of a triangle.
  }
}
 
// Visitable Elements
class Circle {
  accept(visitor) {
    visitor.visitCircle(this);
  }
}
 
class Square {
  accept(visitor) {
    visitor.visitSquare(this);
  }
}
 
class Triangle {
  accept(visitor) {
    visitor.visitTriangle(this);
  }
}

Now, you can use the Visitor pattern to calculate areas and perimeters of shapes without modifying their individual classes:

const circle = new Circle();
const square = new Square();
const triangle = new Triangle();
const areaCalculator = new AreaCalculator();
const perimeterCalculator = new PerimeterCalculator();
const circleArea = circle.accept(areaCalculator);
const squarePerimeter = square.accept(perimeterCalculator);
const triangleArea = triangle.accept(areaCalculator);

Note: In above example, the Visitor pattern allows you to perform different operations (calculating area and perimeter) on different types of shapes without changing the shape classes themselves. It promotes separation of concerns and extensibility in your code.

Code implementing Visitor Pattern in Javascript

Here’s a JavaScript code implementation of the Visitor pattern for shapes along with sample output:




// Visitor Interface
class ShapeVisitor {
  visitCircle(circle) {}
  visitSquare(square) {}
  visitTriangle(triangle) {}
}
 
// Concrete Visitors
class AreaCalculator extends ShapeVisitor {
  visitCircle(circle) {
    return Math.PI * Math.pow(circle.radius, 2);
  }
 
  visitSquare(square) {
    return Math.pow(square.side, 2);
  }
 
  visitTriangle(triangle) {
    // Assuming Heron's formula for triangle area calculation
    const s = (triangle.sideA + triangle.sideB + triangle.sideC) / 2;
    return Math.sqrt(s * (s - triangle.sideA) * (s - triangle.sideB) * (s - triangle.sideC));
  }
}
 
class PerimeterCalculator extends ShapeVisitor {
  visitCircle(circle) {
    return 2 * Math.PI * circle.radius;
  }
 
  visitSquare(square) {
    return 4 * square.side;
  }
 
  visitTriangle(triangle) {
    return triangle.sideA + triangle.sideB + triangle.sideC;
  }
}
 
// Visitable Elements
class Circle {
  constructor(radius) {
    this.radius = radius;
  }
 
  accept(visitor) {
    return visitor.visitCircle(this);
  }
}
 
class Square {
  constructor(side) {
    this.side = side;
  }
 
  accept(visitor) {
    return visitor.visitSquare(this);
  }
}
 
class Triangle {
  constructor(sideA, sideB, sideC) {
    this.sideA = sideA;
    this.sideB = sideB;
    this.sideC = sideC;
  }
 
  accept(visitor) {
    return visitor.visitTriangle(this);
  }
}
 
// Usage
const circle = new Circle(5);
const square = new Square(4);
const triangle = new Triangle(3, 4, 5);
 
const areaCalculator = new AreaCalculator();
const perimeterCalculator = new PerimeterCalculator();
 
const circleArea = circle.accept(areaCalculator);
const squarePerimeter = square.accept(perimeterCalculator);
const triangleArea = triangle.accept(areaCalculator);
 
console.log(`Circle Area: ${circleArea}`);
console.log(`Square Perimeter: ${squarePerimeter}`);
console.log(`Triangle Area: ${triangleArea}`);

Output
Circle Area: 78.53981633974483
Square Perimeter: 16
Triangle Area: 6




In this code, we calculate the area of a circle, the perimeter of a square, and the area of a triangle using the Visitor pattern. The results are printed to the console.

Diagram of Visitor Pattern in Javascript Design Patterns

In this simplified diagram:

Flow diagram of Visitor Method

In the diagram, arrows indicate relationships, such as inheritance (extends) and interface implementation (implements). This simplified UML class diagram illustrates the core components and relationships in the Visitor pattern in JavaScript.

Advantages of the Visitor Pattern in JavaScript Design Patterns

Disadvantages of the Visitor Pattern in JavaScript Design Patterns

Uses of the Visitor Pattern

The Visitor pattern is a powerful design pattern used in various scenarios in software development. Here are some common use cases for the Visitor pattern:

Conclusion

It’s important to note that while the Visitor pattern provides benefits in these scenarios, it also introduces some complexities, especially in terms of maintaining a clean separation of concerns and managing the relationships between elements and visitors. Therefore, its usage should be considered carefully based on the specific requirements of the application or system being developed.


Article Tags :