2012-03-22 26 views
10

Por lo que yo entiendo, el patrón de visitante a menudo se usa para agregar métodos a alguna estructura jerárquica. Pero todavía no lo entiendo: ver el ejemplo en el trato de resaltar subárbol izquierdo:¿Cómo implementar el patrón de visitante en javascript?

subtree highlighting

Javascript aplicación árbol:

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

Creo que estoy usando el patrón de visitantes destacando:

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

Pero por qué utilizar accept-visitar métodos, cuando puede ser más sencillo?

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

Es similar a this example. ¿Significa que si los tipos de mezcla de idiomas (como javascript), no hay ninguna razón para aceptar-visitar el par en absoluto?

Respuesta

15

Te perdiste algo en la implementación. Imagine que las propiedades izquierda y derecha del elemento Nodo eran privadas. Entonces, ¿cómo los destacarías en tu implementación?

El visitante no debe tener en cuenta la estructura de árbol y dejar que el elemento nodo ejecute el visitante en cualquier subelemento que sea un elemento secundario directo. Así que el código debe tener este aspecto:

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

De esta manera el visitante no tiene conocimiento de la estructura del árbol, es genérico y funcionará en cualquier nodo que tiene la propiedad "valor".

+1

Estaba cegado con este error en el libro de J.Bishops. Pasé horas meditando al respecto, ahora está perfectamente claro, ¡muchas gracias! –

+0

Esto es bastante viejo, pero estoy luchando para resolver la diferencia entre lo que está escrito allí, y esto: '' ' node.prototype.accept = function (visitor) { visitor (this); this.left && this.left.accept (visitante); this.right && this.right.accept (visitante); } '' ' La diferencia principal es que en lugar de pasar un objeto con un método de visita, en su lugar, solo se pasa una función. Parece que los ejemplos de patrones de visitantes que ve son lenguajes sin funciones de primera clase, y simplemente usa el objeto para transportar un método. ¿Qué puede hacer su respuesta que la mía no puede, en todo caso? – Tom

+1

@Tom ¿Dónde va a recopilar su función los valores si es necesario? Como es una función, no tendrá un "esto" válido (http://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work). Al usar un objeto en su lugar, puede almacenar todo lo que desee en él. – Bae

Cuestiones relacionadas