Как реализовать шаблон посетителя в JavaScript? - PullRequest
12 голосов
/ 23 марта 2012

Насколько я понимаю, шаблон посетителя часто используется для добавления методов в некоторую иерархическую структуру.Но я все еще не понимаю: посмотрите пример, где я пытаюсь выделить левое поддерево:

subtree highlighting

Реализация дерева JavaScript:

  function node(val) {
    this.value = val;
    this.left = this.right = null;
  }

  var tree = new node("A");
  tree.left = new node("B1");
  tree.right = new node("B2");
  tree.left.left = new node("C1");
  tree.left.right = new node("C2");

Я думаюЯ использую подсветку шаблона посетителя:

node.prototype.accept = function(visitorObj) {
  visitorObj.visit(this);
}

function visitor() {
  var that = this;
  this.visit = function(tgt) {
    tgt.value = "*"+tgt.value;
  }
  this.highlight = function(tgt) {
    tgt.accept(that);
    if(tgt.left) that.highlight(tgt.left);
    if(tgt.right) that.highlight(tgt.right);
  }
}

(new visitor()).highlight(tree.left);

Но зачем использовать методы accept-visit , когда это может быть более простым?

function visitor() {
  var that = this;
  this.highlight = function(tgt) {
    tgt.value = "*"+tgt.value;
    if(tgt.left) that.highlight(tgt.left);
    if(tgt.right) that.highlight(tgt.right);
  }
}

(new visitor()).highlight(tree.left);

Это похоже этот пример .Означает ли это, что если типы языков смешиваются (например, javascript), то нет никакой причины для пары «принять-посещение»?

1 Ответ

17 голосов
/ 23 марта 2012

Вы что-то пропустили в реализации.Представьте, что левые и правые свойства элемента Node были приватными.Тогда как бы вы выделили их в своей реализации?

Посетитель не должен знать о древовидной структуре и разрешать элементу узла запускать посетителя на любом подчиненном элементе, который является прямым дочерним элементом.Таким образом, ваш код должен выглядеть следующим образом:

node.prototype.accept = function(visitorObj) {
    visitorObj.visit(this);
    if (this.left) this.left.accept(visitorObj);
    if (this.right) this.right.accept(visitorObj);
}

function visitor() {
    var that = this;
    this.visit = function(tgt) {
        tgt.value = "*"+tgt.value;
    }
    this.highlight = function(tgt) {
        tgt.accept(that);
    }
}

(new visitor()).highlight(tree.left);

Таким образом, посетитель не знает структуры дерева, он является универсальным и будет работать на любом узле, у которого есть свойство «значение».

...