visitor (patrón de diseño).pdf

9
Visitor (patrón de diseño) 1 Visitor (patrón de diseño) Visitor: diagrama de clases UML. En programación orientada a objetos, el patrón visitor es una forma de separar el algoritmo de la estructura de un objeto. 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 éste 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 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. 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 sólo "visita" al animal, y aplica la cura apropiada.

Upload: fernando-grille

Post on 28-Nov-2015

28 views

Category:

Documents


4 download

TRANSCRIPT

Page 1: Visitor (patrón de diseño).pdf

Visitor (patrón de diseño) 1

Visitor (patrón de diseño)

Visitor: diagrama de clases UML.

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

La idea básica es que se tiene unconjunto de clases elemento queconforman la estructura de un objeto.Cada una de estas clases elementotiene un método aceptar (accept()) querecibe al objeto visitante (visitor) comoargumento. El visitante es una interfazque tiene un método visit diferentepara cada clase elemento; por tantohabrá implementaciones de la interfazvisitor de la forma: visitorClase1,visitorClase2... visitorClaseN. Elmétodo accept de una clase elementollama 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 deun par de clases: el visitante concreto y clase elemento particular. Así el patrón visitor simula el envío doble (eninglés éste 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ássencilla, 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 almé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 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 enbase a 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 propioanimal el que le dice al veterinario qué cura es más apropiada para él. El veterinario sólo "visita" al animal, yaplica la cura apropiada.

Page 2: Visitor (patrón de diseño).pdf

Visitor (patrón de diseño) 2

PropósitoEs un patrón de comportamiento, que permite definir una operación sobre objetos de una jerarquía de clases sinmodificar las clases sobre las que opera. Representa una operación que se realiza sobre los elementos que conformanla 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, sinoque esté fuera, para que cada vez que haya un cambio no haya que cambiarlo todo. Esta opción, además, obliga atener que definir cada operación que necesite el cliente en cada clase de la jerarquía, y a que los clientes conozcanoperaciones que no necesita, ya que sólo 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 otrasclases. Esto es útil si hay un buen número de instancias de un pequeño número de clases y se desea realizar algunaoperación que involucra a todas o a la mayoría de ellas.

Page 3: Visitor (patrón de diseño).pdf

Visitor (patrón de diseño) 3

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”

AplicabilidadEl patrón visitante es aplicable, por ejemplo, cuando varias clases de objetos con interfaces diferentes y se deseanrealizar operaciones que dependen de sus clases concretas. También cuando se necesitan diversas operaciones sobreobjetos 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 laestructura.Si la jerarquía cambia no es aplicable, ya que cada vez que agrega nuevas clases que deben ser visitadas, hay queañadir una operación “visita” abstracta a la clase abstracta del visitante, y debe agregar una aplicación de dichacategoría a cada Visitante concreto que se haya escrito.

Page 4: Visitor (patrón de diseño).pdf

Visitor (patrón de diseño) 4

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 pasacomo argumento para permitir al visitante el acceso a su estado.

ConsecuenciasEs fácil añadir nuevas operaciones a un programa utilizando Visitantes, ya que el visitante contiene el código enlugar de cada una de las clases individuales. Además, los visitantes pueden recoger las operaciones relacionadas enuna sola clase en lugar de obligar a cambiar o derivar clases para agregar estas operaciones. Esto puede hacer alprograma 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 variasclases. Los patrones de diseño sugieren que el visitante puede proporcionar una funcionalidad adicional a una clasesin cambiarla. Pero es más práctico decir que un visitante puede agregar funcionalidad a una colección de clases yencapsular 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 nopueden 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 losvisitantes.Facilita la acumulación de estado, es decir, acumular resultados.

Page 5: Visitor (patrón de diseño).pdf

Visitor (patrón de diseño) 5

Ejemplo de implementaciónEn el ejemplo de a continuación, habrá una jerarquía de expresiones aritméticas simples sobre las que se deseadefinir visitantes. Uno de los visitantes será la operación PrettyPrint que convierte a cadena de caracteres laexpresió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; }

Page 6: Visitor (patrón de diseño).pdf

Visitor (patrón de diseño) 6

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

Page 7: Visitor (patrón de diseño).pdf

Visitor (patrón de diseño) 7

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

}

Page 8: Visitor (patrón de diseño).pdf

Visitor (patrón de diseño) 8

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

}

}

Page 9: Visitor (patrón de diseño).pdf

Fuentes y contribuyentes del artículo 9

Fuentes y contribuyentes del artículoVisitor (patrón de diseño)  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 anónimas

Fuentes de imagen, Licencias y contribuyentesArchivo: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 RitucciArchivo:Visittante.png  Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:Visittante.png  Licencia: Creative Commons Zero  Contribuyentes: AlbagmArchivo:estructura.png  Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:Estructura.png  Licencia: Creative Commons Attribution-Sharealike 3.0  Contribuyentes: User:AlbagmArchivo:colaboraciones.png  Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:Colaboraciones.png  Licencia: Creative Commons Attribution-Sharealike 3.0  Contribuyentes:User:AlbagmArchivo:EjemploImplementacion.png  Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:EjemploImplementacion.png  Licencia: Creative Commons Attribution-Sharealike 3.0 Contribuyentes: User:Albagm

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