2012-03-22 11 views
10

私が理解する限り、ビジターパターンは、いくつかの階層構造にメソッドを追加するためによく使われます。私は左のサブツリーを強調しようとする例を参照してください:しかし、私はまだそれを得ることはありませんjavascriptでビジターパターンを実装する方法は?

subtree highlighting

Javascriptのツリーの実装:私は、私が強調しVisitorパターンを使用しています考えて

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); 

受け入れ訪問の方が、より簡単にできるのはなぜですか?

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); 

this exampleと似ています。言語混合型(javascriptなど)の場合は、受け入れペアの理由がないことを意味しますか?

答えて

15

あなたは実装で何かを逃しました。 Node要素のleftプロパティとrightプロパティがプライベートであるとします。それでは、あなたの実装でどのように強調しますか?

訪問者はツリー構造を認識しておらず、ノード要素が訪問先を直接の子要素である任意のサブ要素に対して実行させるべきではありません。だからあなたのコードは次のようになります。

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); 

この方法では、訪問者が木の構造の知識を持たない、それは一般的なものであり、財産「の値を」持っている任意のノード上で動作します。

+1

J.Bishopsの本でこの間違いで盲目になった。私はそれについて瞑想する時間を過ごしましたが、今は完璧です - ありがとう! –

+0

これはかなり古いバンプですが、そこに書かれている内容とこれとの違いを解決するためには苦労しています: '' ' node.prototype.accept = function(visitor){ visitor(this); this.left && this.left.accept(ビジター); this.right && this.right.accept(visitor); } '' ' 主な違いは、visitメソッドでオブジェクトを渡す代わりに、単に関数を渡すことです。あなたが見ているビジターパターンの例は、ファーストクラスの関数を持たない言語のためのものであり、オブジェクトを使ってメソッドをトランスポートするだけのようです。 私の答えは何か、もしあれば何ができますか? – Tom

+1

@Tomあなたの関数は、必要に応じて値を照合する場所はどこですか?それ以来、それは有効な "this"(http://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work)を持っていません。代わりにオブジェクトを使用することで、必要なものを格納することができます。 – Bae

関連する問題