fbpx
Wikipedia

Visitor (patrón de diseño)

En programación orientada a objetos, el patrón visitor es una forma de separar el algoritmo de la estructura de un objeto.

Visitor: diagrama de clases UML.

La idea básica es que se tiene un conjunto de clases elemento que conforman la estructura de un objeto. Cada una de estas clases elemento tiene un método aceptar (accept()) que recibe al objeto visitante (visitor) como argumento. El visitante es una interfaz que tiene un método visit diferente para cada clase elemento; por tanto habrá implementaciones de la interfaz visitor de la forma: visitorClase1, visitorClase2... visitorClaseN. El método accept de una clase elemento llama al método visit de su clase. Clases concretas de un visitante pueden entonces ser escritas para hacer una operación en particular.

Cada método visit de un visitante concreto puede ser pensado como un método que no es de una sola clase, sino de un par de clases: el visitante concreto y clase elemento particular. Así el patrón visitor simula el envío doble (en inglés este término se conoce como Double-Dispatch) en un lenguaje convencional orientado a objetos de envío único (Single-Dispatch), como son Java o C++.

El patrón visitor también especifica cómo sucede la interacción en la estructura del objeto. En su versión más sencilla, donde cada algoritmo necesita iterar de la misma forma, el método accept de un elemento contenedor, además de una llamada al método visit del objeto visitor, también pasa el objeto visitor como argumento al llamar al método accept de todos sus elementos hijos.

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

Explicación muy sencilla

  • Método simple sin usar este patrón: supongamos un veterinario a domicilio, que con base al animal que tiene que curar sabe qué cura tiene que aplicar. Es responsabilidad del veterinario el saber de qué clase es el animal y sobre la base de ello aplicar la cura.
  • Método usando el patrón: El veterinario no tiene que reconocer al animal ni saber qué cura aplicarle. Es el propio animal el que le dice al veterinario qué cura es más apropiada para él. El veterinario solo "visita" al animal, y aplica la cura apropiada.

Propósito

Es un patrón de comportamiento, que permite definir una operación sobre objetos de una jerarquía de clases sin modificar las clases sobre las que opera. Representa una operación que se realiza sobre los elementos que conforman la estructura de un objeto.

A continuación se detalla un caso en el que sería de gran utilidad aplicar dicho patrón

 

Uno de los principales problemas que presenta este diseño, es querer que la operación f() no esté en la jerarquía, sino que esté fuera, para que cada vez que haya un cambio no haya que cambiarlo todo. Esta opción, además, obliga a tener que definir cada operación que necesite el cliente en cada clase de la jerarquía, y a que los clientes conozcan operaciones que no necesita, ya que solo interesa que conozca las que va a manejar.

El patrón Visitante, cambia el modelo orientado a objetos y crea una clase externa para actuar en los datos en otras clases. Esto es útil si hay un buen número de instancias de un pequeño número de clases y se desea realizar alguna operación que involucra a todas o a la mayoría de ellas.

Estructura

 

Donde:

  • Visitante (Visitor): Declara una operación de visita para cada elemento concreto en la estructura de objetos, que incluye el propio objeto visitado
  • Visitante Concreto (ConcreteVisitor1/2): Implementa las operaciones del visitante y acumula resultados como estado local
  • Elemento (Element): Define una operación “Accept” que toma un visitante como argumento
  • Elemento Concreto (ConcreteElementA/B): Implementa la operación “Accept”

Aplicabilidad

El patrón visitante es aplicable, por ejemplo, cuando varias clases de objetos con interfaces diferentes y se desean realizar operaciones que dependen de sus clases concretas. También cuando se necesitan diversas operaciones sobre objetos de una jerarquía y no se desea recargar las clases con estas operaciones.

Es de mucha utilidad cuando las clases de la jerarquía no cambian, pero se añaden con frecuencia operaciones a la estructura.

Si la jerarquía cambia no es aplicable, ya que cada vez que agrega nuevas clases que deben ser visitadas, hay que añadir una operación “visita” abstracta a la clase abstracta del visitante, y debe agregar una aplicación de dicha categoría a cada Visitante concreto que se haya escrito.

Colaboraciones

 

El cliente visitará a cada elemento de la estructura de objetos con un visitante concreto (previamente creado por él). Cuando se visita un elemento, éste llama a la operación del visitante correspondiente a su clase. El objeto se pasa como argumento para permitir al visitante el acceso a su estado.

Consecuencias

Es fácil añadir nuevas operaciones a un programa utilizando Visitantes, ya que el visitante contiene el código en lugar de cada una de las clases individuales. Además, los visitantes pueden recoger las operaciones relacionadas en una sola clase en lugar de obligar a cambiar o derivar clases para agregar estas operaciones. Esto puede hacer al programa más sencillo de escribir y mantener.

El patrón Visitante es útil cuando se desea encapsular buscando datos desde un número de instancias de varias clases. Los patrones de diseño sugieren que el visitante puede proporcionar una funcionalidad adicional a una clase sin cambiarla. Pero es más práctico decir que un visitante puede agregar funcionalidad a una colección de clases y encapsular los métodos que utiliza.

Se pueden tener problemas con la encapsulación, la solución para ello es que como los atributos de los elementos no pueden ser públicos se hace que todo este en un mismo paquete, es decir, visibilidad de paquete.

Como se comenta anteriormente, es difícil añadir nuevas clases de elementos, ya que obliga a cambiar a los visitantes.

Facilita la acumulación de estado, es decir, acumular resultados.

Ejemplo de implementación

En el ejemplo de a continuación, habrá una jerarquía de expresiones aritméticas simples sobre las que se desea definir visitantes. Uno de los visitantes será la operación PrettyPrint que convierte a cadena de caracteres la expresión aritmética. Mediante la siguiente estructura se comprenderá mejor el ejemplo:

 

/*  * Esta es la superclase de una jerarquía que permite representar expresiones   * aritméticas simples y sobre la que deseamos definir visitantes.   */ package expresion; public abstract class Expresion { abstract public void aceptar(VisitanteExpresion v); } package expresion; public class Constante extends Expresion { public Constante(int valor) { _valor = valor; } public void aceptar(VisitanteExpresion v) { v.visitarConstante(this); } int _valor; } package expresion; public class Variable extends Expresion { public Variable(String variable) { _variable = variable; } public void aceptar(VisitanteExpresion v) { v.visitarVariable(this); } String _variable; } package expresion; public abstract class OpBinaria extends Expresion { public OpBinaria(Expresion izq, Expresion der) { _izq = izq; _der = der; } Expresion _izq, _der; } package expresion; public class Suma extends OpBinaria { public Suma(Expresion izq, Expresion der) { super(izq, der); } public void aceptar(VisitanteExpresion v) { v.visitarSuma(this); } } package expresion; public class Mult extends OpBinaria { public Mult(Expresion izq, Expresion der) { super(izq, der); } public void aceptar(VisitanteExpresion v) { v.visitarMult(this); } } /*  * Esta es la clase abstracta que define la interfaz de los visitantes  * de la jerarquía Expresion -- en realidad, utilizamos una interfaz Java  * dado que todos los métodos son abstractos.   */ package expresion; public interface VisitanteExpresion { public void visitarSuma(Suma s); public void visitarMult(Mult m); public void visitarVariable(Variable v); public void visitarConstante(Constante c); } /**  * Uno de los posibles visitantes de las Expresiones es un pretty printer  * que convierte a cadena de caracteres la expresión aritmética. El algoritmo  * usado no optimiza el uso de paréntesis... El resultado se acumula en  * el atributo privado _resultado, pudiéndose acceder a éste desde el exterior  * mediante el método obtenerResultado()  */ package expresion; public class PrettyPrinterExpresion implements VisitanteExpresion { // visitar la variable en este caso es guardar en el resultado la variable // asociada al objeto... Observe que accedemos al estado interno del objeto // confiando en la visibilidad de paquete... public void visitarVariable(Variable v) { _resultado = v._variable; } public void visitarConstante(Constante c) { _resultado = String.valueOf(c._valor); } // Dado que el pretty-printer de una operación binaria es casi idéntica, // puedo factorizar parte del código con este método privado... private void visitarOpBinaria(OpBinaria op, String pOperacion) { op._izq.aceptar(this); String pIzq = obtenerResultado(); op._der.aceptar(this); String pDer = obtenerResultado(); _resultado = "(" + pIzq + pOperacion + pDer + ")"; } // Por último la visita de la suma y la mult se resuelve mediante el método // privado que se acaba de mencionar... public void visitarSuma(Suma s) { visitarOpBinaria(s, "+"); } public void visitarMult(Mult m) { visitarOpBinaria(m, "*"); } // El resultado se almacena en un String privado. Se proporciona un método // de acceso público para que los clientes del visitante puedan acceder // al resultado de la visita public String obtenerResultado() { return _resultado; } private String _resultado; } import expresion.*; class Main { static public void main(String argv[]) { // Construcción de una expresión (a+5)*(b+1) Expresion expresion = new Mult( new Suma( new Variable("a"), new Constante(5) ), new Suma( new Variable("b"), new Constante(1) )); // Pretty-printing... PrettyPrinterExpresion pretty = new PrettyPrinterExpresion(); expresion.aceptar(pretty); // Visualizacion de resultados System.out.println("Resultado: " + pretty.obtenerResultado()); } } 
  •   Datos: Q830719
  •   Multimedia: Visitor pattern

visitor, patrón, diseño, programación, orientada, objetos, patrón, visitor, forma, separar, algoritmo, estructura, objeto, visitor, diagrama, clases, idea, básica, tiene, conjunto, clases, elemento, conforman, estructura, objeto, cada, estas, clases, elemento,. En programacion orientada a objetos el patron visitor es una forma de separar el algoritmo de la estructura de un objeto Visitor diagrama de clases UML La idea basica es que se tiene un conjunto de clases elemento que conforman la estructura de un objeto Cada una de estas clases elemento tiene un metodo aceptar accept que recibe al objeto visitante visitor como argumento El visitante es una interfaz que tiene un metodo visit diferente para cada clase elemento por tanto habra implementaciones de la interfaz visitor de la forma visitorClase1 visitorClase2 visitorClaseN El metodo accept de una clase elemento llama al metodo visit de su clase Clases concretas de un visitante pueden entonces ser escritas para hacer una operacion en particular Cada metodo visit de un visitante concreto puede ser pensado como un metodo que no es de una sola clase sino de un par de clases el visitante concreto y clase elemento particular Asi el patron visitor simula el envio doble en ingles este termino se conoce como Double Dispatch en un lenguaje convencional orientado a objetos de envio unico Single Dispatch como son Java o C El patron visitor tambien especifica como sucede la interaccion en la estructura del objeto En su version mas sencilla donde cada algoritmo necesita iterar de la misma forma el metodo accept de un elemento contenedor ademas de una llamada al metodo visit del objeto visitor tambien pasa el objeto visitor como argumento al llamar al metodo accept de todos sus elementos hijos Este patron es ampliamente utilizado en interpretes compiladores y procesadores de lenguajes en general Indice 1 Explicacion muy sencilla 2 Proposito 3 Estructura 4 Aplicabilidad 5 Colaboraciones 6 Consecuencias 7 Ejemplo de implementacionExplicacion muy sencilla EditarMetodo simple sin usar este patron supongamos un veterinario a domicilio que con base al animal que tiene que curar sabe que cura tiene que aplicar Es responsabilidad del veterinario el saber de que clase es el animal y sobre la base de ello aplicar la cura Metodo usando el patron El veterinario no tiene que reconocer al animal ni saber que cura aplicarle Es el propio animal el que le dice al veterinario que cura es mas apropiada para el El veterinario solo visita al animal y aplica la cura apropiada Proposito EditarEs un patron de comportamiento que permite definir una operacion sobre objetos de una jerarquia de clases sin modificar las clases sobre las que opera Representa una operacion que se realiza sobre los elementos que conforman la estructura de un objeto A continuacion se detalla un caso en el que seria de gran utilidad aplicar dicho patron Uno de los principales problemas que presenta este diseno es querer que la operacion f no este en la jerarquia sino que este fuera para que cada vez que haya un cambio no haya que cambiarlo todo Esta opcion ademas obliga a tener que definir cada operacion que necesite el cliente en cada clase de la jerarquia y a que los clientes conozcan operaciones que no necesita ya que solo interesa que conozca las que va a manejar El patron Visitante cambia el modelo orientado a objetos y crea una clase externa para actuar en los datos en otras clases Esto es util si hay un buen numero de instancias de un pequeno numero de clases y se desea realizar alguna operacion que involucra a todas o a la mayoria de ellas Estructura Editar Donde Visitante Visitor Declara una operacion de visita para cada elemento concreto en la estructura de objetos que incluye el propio objeto visitado Visitante Concreto ConcreteVisitor1 2 Implementa las operaciones del visitante y acumula resultados como estado local Elemento Element Define una operacion Accept que toma un visitante como argumento Elemento Concreto ConcreteElementA B Implementa la operacion Accept Aplicabilidad EditarEl patron visitante es aplicable por ejemplo cuando varias clases de objetos con interfaces diferentes y se desean realizar operaciones que dependen de sus clases concretas Tambien cuando se necesitan diversas operaciones sobre objetos de una jerarquia y no se desea recargar las clases con estas operaciones Es de mucha utilidad cuando las clases de la jerarquia no cambian pero se anaden con frecuencia operaciones a la estructura Si la jerarquia cambia no es aplicable ya que cada vez que agrega nuevas clases que deben ser visitadas hay que anadir una operacion visita abstracta a la clase abstracta del visitante y debe agregar una aplicacion de dicha categoria a cada Visitante concreto que se haya escrito Colaboraciones Editar El cliente visitara a cada elemento de la estructura de objetos con un visitante concreto previamente creado por el Cuando se visita un elemento este llama a la operacion del visitante correspondiente a su clase El objeto se pasa como argumento para permitir al visitante el acceso a su estado Consecuencias EditarEs facil anadir nuevas operaciones a un programa utilizando Visitantes ya que el visitante contiene el codigo en lugar de cada una de las clases individuales Ademas los visitantes pueden recoger las operaciones relacionadas en una sola clase en lugar de obligar a cambiar o derivar clases para agregar estas operaciones Esto puede hacer al programa mas sencillo de escribir y mantener El patron Visitante es util cuando se desea encapsular buscando datos desde un numero de instancias de varias clases Los patrones de diseno sugieren que el visitante puede proporcionar una funcionalidad adicional a una clase sin cambiarla Pero es mas practico decir que un visitante puede agregar funcionalidad a una coleccion de clases y encapsular los metodos que utiliza Se pueden tener problemas con la encapsulacion la solucion para ello es que como los atributos de los elementos no pueden ser publicos se hace que todo este en un mismo paquete es decir visibilidad de paquete Como se comenta anteriormente es dificil anadir nuevas clases de elementos ya que obliga a cambiar a los visitantes Facilita la acumulacion de estado es decir acumular resultados Ejemplo de implementacion EditarEn el ejemplo de a continuacion habra una jerarquia de expresiones aritmeticas simples sobre las que se desea definir visitantes Uno de los visitantes sera la operacion PrettyPrint que convierte a cadena de caracteres la expresion aritmetica Mediante la siguiente estructura se comprendera mejor el ejemplo Esta es la superclase de una jerarquia que permite representar expresiones aritmeticas simples y sobre la que deseamos definir visitantes package expresion public abstract class Expresion abstract public void aceptar VisitanteExpresion v package expresion public class Constante extends Expresion public Constante int valor valor valor public void aceptar VisitanteExpresion v v visitarConstante this int valor package expresion public class Variable extends Expresion public Variable String variable variable variable public void aceptar VisitanteExpresion v v visitarVariable this String variable package expresion public abstract class OpBinaria extends Expresion public OpBinaria Expresion izq Expresion der izq izq der der Expresion izq der package expresion public class Suma extends OpBinaria public Suma Expresion izq Expresion der super izq der public void aceptar VisitanteExpresion v v visitarSuma this package expresion public class Mult extends OpBinaria public Mult Expresion izq Expresion der super izq der public void aceptar VisitanteExpresion v v visitarMult this Esta es la clase abstracta que define la interfaz de los visitantes de la jerarquia Expresion en realidad utilizamos una interfaz Java dado que todos los metodos son abstractos package expresion public interface VisitanteExpresion public void visitarSuma Suma s public void visitarMult Mult m public void visitarVariable Variable v public void visitarConstante Constante c Uno de los posibles visitantes de las Expresiones es un pretty printer que convierte a cadena de caracteres la expresion aritmetica El algoritmo usado no optimiza el uso de parentesis El resultado se acumula en el atributo privado resultado pudiendose acceder a este desde el exterior mediante el metodo obtenerResultado package expresion public class PrettyPrinterExpresion implements VisitanteExpresion visitar la variable en este caso es guardar en el resultado la variable asociada al objeto Observe que accedemos al estado interno del objeto confiando en la visibilidad de paquete public void visitarVariable Variable v resultado v variable public void visitarConstante Constante c resultado String valueOf c valor Dado que el pretty printer de una operacion binaria es casi identica puedo factorizar parte del codigo con este metodo privado private void visitarOpBinaria OpBinaria op String pOperacion op izq aceptar this String pIzq obtenerResultado op der aceptar this String pDer obtenerResultado resultado pIzq pOperacion pDer Por ultimo la visita de la suma y la mult se resuelve mediante el metodo privado que se acaba de mencionar public void visitarSuma Suma s visitarOpBinaria s public void visitarMult Mult m visitarOpBinaria m El resultado se almacena en un String privado Se proporciona un metodo de acceso publico para que los clientes del visitante puedan acceder al resultado de la visita public String obtenerResultado return resultado private String resultado import expresion class Main static public void main String argv Construccion de una expresion a 5 b 1 Expresion expresion new Mult new Suma new Variable a new Constante 5 new Suma new Variable b new Constante 1 Pretty printing PrettyPrinterExpresion pretty new PrettyPrinterExpresion expresion aceptar pretty Visualizacion de resultados System out println Resultado pretty obtenerResultado Datos Q830719 Multimedia Visitor pattern Obtenido de https es wikipedia org w index php title Visitor patron de diseno amp oldid 129023141, wikipedia, wiki, leyendo, leer, libro, biblioteca,

español

, española, descargar, gratis, descargar gratis, mp3, video, mp4, 3gp, jpg, jpeg, gif, png, imagen, música, canción, película, libro, juego, juegos