Visitor (Patrón de Diseño) PDF

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 9

Visitor (patrn de diseo)

Visitor (patrn de diseo)


En programacin orientada a objetos, el patrn visitor es una forma de separar el algoritmo de la estructura de un objeto. La idea bsica es que se tiene un conjunto de clases elemento que conforman la estructura de un objeto. Cada una de estas clases elemento tiene un mtodo aceptar (accept()) que recibe al objeto visitante (visitor) como argumento. El visitante es una interfaz que tiene un mtodo visit diferente para cada clase elemento; por tanto habr implementaciones de la interfaz visitor de la forma: visitorClase1, visitorClase2... visitorClaseN. El Visitor: diagrama de clases UML. mtodo accept de una clase elemento llama al mtodo visit de su clase. Clases concretas de un visitante pueden entonces ser escritas para hacer una operacin en particular. Cada mtodo visit de un visitante concreto puede ser pensado como un mtodo que no es de una sola clase, sino de un par de clases: el visitante concreto y clase elemento particular. As el patrn visitor simula el envo doble (en ingls ste trmino se conoce como Double-Dispatch) en un lenguaje convencional orientado a objetos de envo nico (Single-Dispatch), como son Java o C++. El patrn visitor tambin especifica cmo sucede la interaccin en la estructura del objeto. En su versin ms sencilla, donde cada algoritmo necesita iterar de la misma forma, el mtodo accept de un elemento contenedor, adems de una llamada al mtodo visit del objeto visitor, tambin pasa el objeto visitor como argumento al llamar al mtodo accept de todos sus elementos hijos. Este patrn es ampliamente utilizado en intrpretes, compiladores y procesadores de lenguajes, en general.

Explicacin muy sencilla


Mtodo simple sin usar este patrn: supongamos un veterinario a domicilio, que en 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 en base a ello aplicar la cura. Mtodo usando el patrn: 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 ms apropiada para l. El veterinario slo "visita" al animal, y aplica la cura apropiada.

Visitor (patrn de diseo)

Propsito
Es un patrn de comportamiento, que permite definir una operacin sobre objetos de una jerarqua de clases sin modificar las clases sobre las que opera. Representa una operacin que se realiza sobre los elementos que conforman la estructura de un objeto. A continuacin se detalla un caso en el que sera de gran utilidad aplicar dicho patrn

Uno de los principales problemas que presenta este diseo, es querer que la operacin f() no est en la jerarqua, sino que est fuera, para que cada vez que haya un cambio no haya que cambiarlo todo. Esta opcin, adems, obliga a tener que definir cada operacin que necesite el cliente en cada clase de la jerarqua, y a que los clientes conozcan operaciones que no necesita, ya que slo interesa que conozca las que va a manejar. El patrn 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 nmero de instancias de un pequeo nmero de clases y se desea realizar alguna operacin que involucra a todas o a la mayora de ellas.

Visitor (patrn de diseo)

Estructura

Donde: Visitante (Visitor): Declara una operacin 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 operacin Accept que toma un visitante como argumento Elemento Concreto (ConcreteElementA/B): Implementa la operacin Accept

Aplicabilidad
El patrn visitante es aplicable, por ejemplo, cuando varias clases de objetos con interfaces diferentes y se desean realizar operaciones que dependen de sus clases concretas. Tambin cuando se necesitan diversas operaciones sobre objetos de una jerarqua y no se desea recargar las clases con estas operaciones. Es de mucha utilidad cuando las clases de la jerarqua no cambian, pero se aaden con frecuencia operaciones a la estructura. Si la jerarqua cambia no es aplicable, ya que cada vez que agrega nuevas clases que deben ser visitadas, hay que aadir una operacin visita abstracta a la clase abstracta del visitante, y debe agregar una aplicacin de dicha categora a cada Visitante concreto que se haya escrito.

Visitor (patrn de diseo)

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 operacin del visitante correspondiente a su clase. El objeto se pasa como argumento para permitir al visitante el acceso a su estado.

Consecuencias
Es fcil aadir nuevas operaciones a un programa utilizando Visitantes, ya que el visitante contiene el cdigo en lugar de cada una de las clases individuales. Adems, 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 ms sencillo de escribir y mantener. El patrn Visitante es til cuando se desea encapsular buscando datos desde un nmero de instancias de varias clases. Los patrones de diseo sugieren que el visitante puede proporcionar una funcionalidad adicional a una clase sin cambiarla. Pero es ms prctico decir que un visitante puede agregar funcionalidad a una coleccin de clases y encapsular los mtodos que utiliza. Se pueden tener problemas con la encapsulacin, la solucin para ello es que como los atributos de los elementos no pueden ser pblicos se hace que todo este en un mismo paquete, es decir, visibilidad de paquete. Como se comenta anteriormente, es difcil aadir nuevas clases de elementos, ya que obliga a cambiar a los visitantes. Facilita la acumulacin de estado, es decir, acumular resultados.

Visitor (patrn de diseo)

Ejemplo de implementacin
En el ejemplo de a continuacin, habr una jerarqua de expresiones aritmticas simples sobre las que se desea definir visitantes. Uno de los visitantes ser la operacin PrettyPrint que convierte a cadena de caracteres la expresin aritmtica. Mediante la siguiente estructura se comprender mejor el ejemplo:

/* * Esta es la superclase de una jerarqua que permite representar expresiones * aritmticas 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; }

Visitor (patrn de diseo) 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 jerarqua Expresion -- en realidad, utilizamos una interfaz Java * dado que todos los mtodos 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 expresin aritmtica. El algoritmo * usado no optimiza el uso de parntesis... El resultado se acumula en * el atributo privado _resultado, pudindose acceder a ste desde el exterior * mediante el mtodo 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

Visitor (patrn de diseo) // 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 operacin binaria es casi idntica, // puedo factorizar parte del cdigo con este mtodo 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 mtodo // 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 mtodo // de acceso pblico para que los clientes del visitante puedan acceder // al resultado de la visita public String obtenerResultado() { return _resultado; } private String _resultado; }

Visitor (patrn de diseo) import expresion.*; class Main { static public void main(String argv[]) { // Construccin de una expresin (a+5)*(b+1) Expresion expresion = new Mult( new Suma( new new new Suma( new new

Variable("a"), Constante(5) ), Variable("b"), Constante(1) ));

// Pretty-printing... PrettyPrinterExpresion pretty = new PrettyPrinterExpresion(); expresion.aceptar(pretty); // Visualizacion de resultados System.out.println("Resultado: " + pretty.obtenerResultado()); } }

Fuentes y contribuyentes del artculo

Fuentes y contribuyentes del artculo


Visitor (patrn de diseo) Fuente: http://es.wikipedia.org/w/index.php?oldid=68069210 Contribuyentes: Albagm, Biasoli, BlackBeast, Davinci78, Digigalos, Dusan, Er Komandante, GermanX, JavierCantero, LarA, Lucasontivero, PayoMalayo, Pilaf, Porao, Rdcorbera, 17 ediciones annimas

Fuentes de imagen, Licencias y contribuyentes


Archivo:Visitor UML class diagram.svg Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:Visitor_UML_class_diagram.svg Licencia: GNU Free Documentation License Contribuyentes: Giacomo Ritucci Archivo:Visittante.png Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:Visittante.png Licencia: Creative Commons Zero Contribuyentes: Albagm Archivo:estructura.png Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:Estructura.png Licencia: Creative Commons Attribution-Sharealike 3.0 Contribuyentes: User:Albagm Archivo:colaboraciones.png Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:Colaboraciones.png Licencia: Creative Commons Attribution-Sharealike 3.0 Contribuyentes: User:Albagm Archivo:EjemploImplementacion.png Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:EjemploImplementacion.png Licencia: Creative Commons Attribution-Sharealike 3.0 Contribuyentes: User:Albagm

Licencia
Creative Commons Attribution-Share Alike 3.0 //creativecommons.org/licenses/by-sa/3.0/

También podría gustarte