Javascript. Visitor pattern

Паттерн Посетитель (Visitor pattern) определяет операцию, выполняемую на каждом элементе некоторой структуры. Позволяет, не изменяя классы этих объектов, добавлять в них новые операции. Как известно, различные и несвязные операции выполняются над узловыми
объектами некоторой гетерогенной совокупной структуры. Чтобы избежать "загрязнения" классов этих узлов такими операциями (то есть избежать добавления соответствующих методов в эти классы), можно воспользоваться паттерном Посетитель. Также в реализации этого паттерна играют роль типы объектов, что позволяет делать типизированный выбор действий. Так как мы имеем дело с Javascript, то здесь это делается немного иначе: через условные конструкции. Данный паттерн относится к паттернам поведения. Ниже редставлена диаграмма классов реализации данного паттерна.

Также ниже представлен пример реализации данного паттерна.

/* internal iterator */

Array.prototype.iterator = function () {
    
    var self = this, position = 0, undefined;
    
    return {
        
        next: function () {
            return self[position++];
        },
        
        hasNext: function () {
            if (position >= self.length) {
                return false;
            } 
            else {
                return true;
            }
        },
        
        remove: function () {
            if (position <= 0) {
                throw new Error("You can`t an item until you`ve done at least one next()");
            }
            if (self[position - 1] !== undefined) {
                for (var i = position - 1; i < (self.length - 1); i++) {
                    self[i] = self[i + 1];
                }
                self[self.length - 1] = undefined;
            }
        }
        
    };
};

/* interface Element */

var ComputerPart = function () {
this.accept = function (computerPartVisitor) {
throw new Error("accept method is not implemented");
};
};

/* ConcreteElement */

var Keyboard = function () {
this.accept = function (computerPartVisitor) {
computerPartVisitor.visit(this);
};
};

Keyboard.prototype = new ComputerPart();
Keyboard.prototype.constructor = Keyboard;

/* ConcreteElement */

var Monitor = function () {
this.accept = function (computerPartVisitor) {
computerPartVisitor.visit(this);
};
};

Monitor.prototype = new ComputerPart();
Monitor.prototype.constructor = Monitor;

/* ConcreteElement */

var Mouse = function () {
this.accept = function (computerPartVisitor) {
computerPartVisitor.visit(this);
};
};

Mouse.prototype = new ComputerPart();
Mouse.prototype.constructor = Mouse;

/* ConcreteElement */

var Computer = function () {

var parts = [new Mouse(), new Keyboard(), new Monitor()];

this.accept = function (computerPartVisitor) {
for (var it = parts.iterator(); it.hasNext();) {
(it.next()).accept(computerPartVisitor);
}
computerPartVisitor.visit(this);
};
};

Computer.prototype = new ComputerPart();
Computer.prototype.constructor = Computer;

/* interface Visitor */

var computerPartVisitor = function () {
this.visit = function (computerPart) {
throw new Error("visit method is not implemented");
};
};

/* ConcreteVisitor */

var computerPartDisplayVisitor = function () {
this.visit = function (computerPart) {
if (computerPart.constructor === Computer) {
console.log("Displaying Computer.");
}
if (computerPart.constructor === Mouse) {
console.log("Displaying Mouse.");
}
if (computerPart.constructor === Keyboard) {
console.log("Displaying Keyboard.");
}
if (computerPart.constructor === Monitor) {
console.log("Displaying Monitor.");
}
};
};

computerPartDisplayVisitor.prototype = new computerPartVisitor();
computerPartDisplayVisitor.constructor = computerPartDisplayVisitor;

/* testing... */

var Application = function () {
this.run = function () {
var computer = new Computer();
computer.accept(new computerPartDisplayVisitor());
};
};

var app = new Application();
app.run();

В итоге получаем:

Displaying Mouse.
Displaying Keyboard.
Displaying Monitor.
Displaying Computer.

Всем успехов.