Dofactory.com
Dofactory.com
Earn income with your JavaScript skills
Sign up and we'll send you the best freelance opportunities straight to your inbox.
We're building the largest freelancing marketplace for people like you.
By adding your name & email you agree to our terms, privacy and cookie policies.

JavaScript Visitor Design Pattern

The Visitor pattern defines a new operation to a collection of objects without changing the objects themselves. The new logic resides in a separate object called the Visitor.

JavaScript Patterns

Using Visitor

Visitors are useful when building extensibility in a library or framework. If the objects in your project provide a 'visit' method that accepts a Visitor object which can make changes to the receiving object then you are providing an easy way for clients to implement future extensions.

In most programming languages the Visitor pattern requires that the original developer anticipates functional adjustments in the future. This is done by including methods that accept a Visitor and let it operate on the original collection of objects.

Visitor is not important to JavaScript because it offers far more flexibility by the ability to add and remove methods at runtime. To learn more about this flexibility and how it benefits JavaScript patterns and pattern architectures see our Dofactory JS.


Diagram

Diagram JavaScript Visitor Design Pattern

Participants

The objects participating in this pattern are:

  • ObjectStructure -- In example code: employees array
    • maintains a collection of Elements which can be iterated over
  • Elements -- In example code: Employee objects
    • defines an accept method that accepts visitor objects
    • in the accept method the visitor's visit method is invoked with 'this' as a parameter
  • Visitor -- In example code: ExtraSalary, ExtraVacation
    • implements a visit method. The argument is the Element being visited. This is where the Element's changes are made


Example

In this example three employees are created with the Employee constructor function. Each is getting a 10% salary raise and 2 more vacation days. Two visitor objects, ExtraSalary and ExtraVacation, make the necessary changes to the employee objects.

Note that the visitors, in their visit methods, access the closure variables salary and vacation through a public interface. It is the only way because closures are not accessible from the outside. In fact, salary and vacation are not variables, they are function arguments, but it works because they are also part of the closure.

Notice the self variable. It is used to maintain the current context (stored as a closure variable) and is used in the visit method.

To learn more about these and other more advanced JavaScript concepts check our Dofactory JS.


var Employee = function (name, salary, vacation) {
    var self = this;

    this.accept = function (visitor) {
        visitor.visit(self);
    };

    this.getName = function () {
        return name;
    };

    this.getSalary = function () {
        return salary;
    };

    this.setSalary = function (sal) {
        salary = sal;
    };

    this.getVacation = function () {
        return vacation;
    };

    this.setVacation = function (vac) {
        vacation = vac;
    };
};

var ExtraSalary = function () {
    this.visit = function (emp) {
        emp.setSalary(emp.getSalary() * 1.1);
    };
};

var ExtraVacation = function () {
    this.visit = function (emp) {
        emp.setVacation(emp.getVacation() + 2);
    };
};

function run() {

    var employees = [
        new Employee("John", 10000, 10),
        new Employee("Mary", 20000, 21),
        new Employee("Boss", 250000, 51)
    ];

    var visitorSalary = new ExtraSalary();
    var visitorVacation = new ExtraVacation();

    for (var i = 0, len = employees.length; i < len; i++) {
        var emp = employees[i];

        emp.accept(visitorSalary);
        emp.accept(visitorVacation);
        console.log(emp.getName() + ": $" + emp.getSalary() +
            " and " + emp.getVacation() + " vacation days");
    }
}

You may also like


Last updated on Sep 30, 2023

Earn income with your JavaScript skills
Sign up and we'll send you the best freelance opportunities straight to your inbox.
We're building the largest freelancing marketplace for people like you.
By adding your name & email you agree to our terms, privacy and cookie policies.
Guides