Visitor

Visitante / Visitor
Información sobre la plantilla
Visittern.png
Concepto:Representa una operación sobre los elementos de una estructura de objetos. Permite definir una nueva operación sin cambiar las clases de los elementos sobre los que opera.


Resumen. Patrón Visitor proporciona una forma fácil y sostenible de ejecutar acciones en una familia de clases. Este patrón centraliza los comportamientos y permite que sean modificados o ampliados sin cambiar las clases sobre las que actúan.

Tipo

Comportamiento, a nivel de objetos.

Propósito

Representa una operación que está pensada para ser aplicada sobre los elementos de una estructura de objetos, permitiendo así definir y añadir un nuevo comportamiento sin necesidad de cambiar las clases de los elementos de la estructura de objetos.

Cuando usarlo

  • Cuando una “Estructura De Objetos” contiene muchas clases con diferentes interfaces y se quieren añadir operaciones a dichos objetos en función de la interfaz.
  • Cuando se quieren añadir a los objetos de una estructura operaciones muy diferentes y sin relación alguna entre ellas, sin necesidad de hacerlo a nivel individual.
  • Cuando las clases que definen la “Estructura De Objetos” casi nunca cambian, pero frecuentemente queremos añadir nuevas operaciones a ciertos objetos de la estructura.

Ventajas

  • Es fácil añadir nuevas operaciones a la “Estructura De Objetos”; sólo hay que crear un nuevo “Visitante”, en vez de cambiar todas las clases a las que queremos que afecte.
  • Se juntan las operaciones relacionadas entre sí, separándose las que nada tienen que ver. Esto simplifica tanto las clases de los “Elementos” como los algoritmos definidos en los “Visitantes”.
  • Se pueden recorrer jerarquías formadas por objetos de distintos tipos (distinta clase padre), mientras que un Iterador no puede hacer esto.
  • Se puede ir acumulando el estado a medida que se recorre la estructura, en vez de tener que pasarlo como parámetro o guardarlo en variables globales.

Inconvenientes

  • Añadir un nuevo tipo de elemento a la estructura de objetos crea problemas, pues hay que tocar toda la estructura jerárquica de “Visitantes”, lo cual es muy costoso.
  • Frecuentemente se fuerza a los “Elementos” a proporcionar operaciones públicas que den acceso a su estado interno, con lo que se pone en peligro el encapsulamiento.

Relacionado con

  • Visitante puede usarse para aplicar una operación sobre una estructura de objetos definida por Composición.
  • Visitante puede utilizarse para implementar la operación de interpretación en el patrón Intérprete.

Otros aspectos de interés

  • La técnica de programación que posibilita añadir operaciones a las clases de la “Estructura De Objetos” sin cambiarlos, recibe el nombre de “double dispatch”, pues su ejecución depende del tipo del peticionario y de los dos receptores: el “Visitante” y el “Elemento”. Hay lenguajes CLOS que lo soportan directamente y otros C++ que sólo tienen “simple dispatch”, por lo que deben pasar el “Visitante” como parámetro.
  • La responsabilidad de recorrer la “Estructura De Objetos” puede recaer en la propia estructura (es frecuente), en un Iterador, que puede ser externo o interno (parecido a la primera opción, salvo en que ahora no hay “double dispatch”) o en el “Visitante” (nos permite implementar una política compleja particular para el recorrido, pero duplica el código en cada “Visitante” concreto).
  • La “Estructura De Objetos” puede ser una composición o una colección de objetos (lista, conjunto,...) que proporciona una interfaz de alto nivel para que el “Visitante” pueda acceder a todos sus “Elementos”.

Ejemplo de aplicación

En un compilador que representa los programas mediante árboles sintácticos abstractos es mejor tener por un lado la jerarquía de nodos (declaraciones de asignación, acceso a variables, expresiones aritméticas, etc...) y por otro las operaciones que queremos aplicarles (comprobación de tipos, generación de código, análisis de flujo, optimizaciones, etc...) que tener todas las operaciones dentro de cada nodo, dado que no a todos los nodos les afectan igual las distintas operaciones.

Fuentes