Visitor

RECU-0203 (Recurso Patrón)

Descripción

Es un patrón que permite definir nuevas operaciones sobre una jerarquía de clases sin modificar las clases sobre las que opera.

Nombre

También se le conoce como Visitante

Clasificación

Es un patrón de Comportamiento

Motivación

Consideremos una aplicación relacionada con compiladores.Estos representan los programa de árboles de sintaxis abstracta sobre los que ejecutan operaciones para realizar su funcionalidad. Muchas de estas operaciones tienen un contexto propio y por lo tnato necesitan diferenciar cierta información (tipo de nodo del árbol). Esto genera un conflicto ya que lo convierte en difícil de implementar y mantener. Las apariciones de nuevos elementos necesitaría recompilar todas las clases existentes.

El patrón Visitor propone una solución a este problema. Pretende independizar las clases de las operaciones que se ejecutan sobre ellas.

Aplicabilidad

Se recomienda le uso del patrón cuando

  • Una estructura de objetos contiene muchas clases de objetos con interfaces distintas, y se quiere realizar sobre ellos operaciones que son distintas en cada clase concreta.
  • Se quieren realizar muchas operaciones distintas sobre los objetos de una estructura, sin incluir dichas operaciones en las clases
  • Las clases que forman la estructura de objetos no cambian pero las operaciones sobre ellas sí

Estructura

La representación gráfica del modelo es la siguiente:

190

Participantes

  • Visitor: Define una operación de visita para cada clase de elemento concreto en la estructura de objetos
  • VisitorConcreto: Implementa la interfaz de Visitor. Cada operación implementa un fragmento de la labor global del VisitorConcreto pudiendo almacenar información local
  • Elemento: Define la operación acepta con el Visitor de argumento
  • ElementoConcreto: implementa la operación acepta
  • EstructuraObjeto: Gestiona la estructura de objetos y puede enumerar sus elementos. Puede ser un compuesto (Composite) o una colección de objetos. Puede ofrecer una interfaz que permita al Visitor visitar a sus elementos

Colaboraciones

Consecuencias

  • Facilita la definición de nuevas operaciones
  • Agrupa operaciones relacionadas
  • Añadir nuevos ElementosConcretos es costos.Utilizar el patrón si la jerarquía es estable
  • Permite atravesar jerarquías de objetos que no estan relacionadas por un padre común
  • Puede acumular el estado de una operación al visitar la estructura de objetos, en vez de pasarlo como argumento o variable glboal.
  • Rompe la encapsulación

Implementación

Para realizar una correcta implementación del patrón se recomienda:

  • Double Dispatch: Técnica que permite añadir operaciones a las clases sin tener que modificarlas. La operación a ejecutar depende de la clase de petición (acepta) y del tipo de los dos receptores (Visitor, Elemento)
  • ¿Quién es responsable de recorrer la estructura de objetos? Un Visitor debe de recorrer cada elemento de la estructura. Podemos hacerlo mediante un objeto de la estructura, un objeto visitor u mediante un iterador. Si lo hacemos mediante un visitor se duplica el código recorrido en cada objeto de tipo compuesto. Sólo se utiliza para implementar recorridos complejos que dependen de los resultados de las operaciones

Código Ejemplo

interface Elemento {
  
   public void acepta( Visitor v );
}
class Uno implements Elemento {
  
   public void   acepta( Visitor v ) {
     v.visit( this );
   }
   public String thiss() {
     return "This";
   }
}
class Dos implements Elemento {
   public void   acepta( Visitor v ) {
     v.visit( this );
   }
   public String dos() {
     return "Dos";
   }
}
class Tres implements Elemento {
   public void   acepta( Visitor v ) {
     v.visit( this );
   }
   public String tres() {
     return "tres";
   }
}
   public void visitar( Uno e );
   public void visitar( Dos e );
   public void visitar( Tres e );
}
class ArribaVisitante implements Visitor {                  
   public void visitar( Uno e ) {
      System.out.println( "hacer Arriba on " + e.uno() );
   }
   public void visitar( Dos e ) {
      System.out.println( "hacer Arriba on " + e.dos() );
   }
   public void visitar( Tres e ) {
      System.out.println( "hacer Arriba on " + e.tres() );
   }
}
class AbajoVisitante implements Visitor {
   public void visitar( Uno e ) {
      System.out.println( "hacer Abajo on " + e.uno() );
   }
   public void visitar( Dos e ) {
      System.out.println( "hacer Abajo on " + e.dos() );
   }
   public void visitar( Tres e ) {
      System.out.println( "hacer Abajo on " + e.tres() );
   }
}

Usos Conocidos

Este patrón es ampliamente utilizado en intérpretes, compiladores y procesadores de lenguajes, en general

Patrones Relacionados

  • Composite: Los Visitor se pueden aplicar sobre objetos de estructuras definidas por Composite
  • Interprete: Los Visitor pueden ser aplicados para realizar la interpretación

Clasificación

Otros

Contenidos relacionados

Recursos
Área: Desarrollo » Aplicaciones Java » Otras Especificaciones de Codificación de Aplicaciones Java
Código Título Tipo Carácter
RECU-0184 Composite Patrón Recomendado
RECU-0192 Interprete Patrón Recomendado