如何在javascript中实现访问者模式?

Jan*_*roň 12 javascript design-patterns visitor-pattern

据我所知,访问者模式通常用于向某些层次结构添加方法.但我仍然没有得到它:看到我尝试突出显示左子树的示例:

子树突出显示

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");
Run Code Online (Sandbox Code Playgroud)

我想我正在使用访客模式突出显示:

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);
Run Code Online (Sandbox Code Playgroud)

但是为什么要使用接受访问方法,何时可以更直接?

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);
Run Code Online (Sandbox Code Playgroud)

它类似于这个例子.这是否意味着如果语言混合类型(如javascript),根本没有接受访问对的理由?

Udi*_*hen 17

你错过了实施中的一些东西.想象一下,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);
Run Code Online (Sandbox Code Playgroud)

这样访问者不了解树的结构,它是通用的,并且可以在具有属性"value"的任何节点上工作.