🎃 Grandes descuentos en libros en línea, eformaciones y vídeos*. Código CALABAZA30. Pulse aquí
¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
  1. Libros
  2. Patrones de diseño en C#
  3. El patrón Visitor
Extrait - Patrones de diseño en C# Los 23 modelos de diseño: descripción y soluciones ilustradas en UML 2 y C# [2ªedición]
Extractos del libro
Patrones de diseño en C# Los 23 modelos de diseño: descripción y soluciones ilustradas en UML 2 y C# [2ªedición] Volver a la página de compra del libro

El patrón Visitor

Descripción

El patrón Visitor construye una operación que debe realizarse sobre los elementos de un conjunto de objetos. Esto permite agregar nuevas operaciones sin modificar las clases de estos objetos.

Ejemplo

Consideremos la figura 4-12.1 que describe los clientes de nuestro sistema organizados bajo la forma de objetos compuestos según el patrón Composite. A excepción del método agregaFilial específico a la gestión de la composición, las dos subclases poseen dos métodos con el mismo nombre: calculaCosteEmpresa y envíaEmailComercial. Cada uno de estos métodos se corresponde con una funcionalidad cuya implementación está bien adaptada en función de la clase. Podrían implementarse muchas otras funcionalidades como por ejemplo el cálculo de la cifra de negocios de un cliente (incluyendo o no sus filiales), etc.

En el diagrama, el cálculo del coste del mantenimiento no está detallado. El detalle se encuentra en el capítulo dedicado al patrón Composite.

Este enfoque puede utilizarse siempre y cuando el número de funcionalidades sea pequeño. En cambio, si se vuelve importante, obtendremos clases con muchos métodos, difíciles de comprender y de mantener. Además, estas funcionalidades darán lugar a métodos (calculaCosteEmpresa y envíaEmailComercial) sin relación entre ellas y sin relación entre el núcleo de los objetos con la diferencia, por ejemplo, del método agregaFilial que contribuye a componer los objetos.

images/figure28-1.png

Figura 4-12.1 - Múltiples funcionalidades...

Estructura

1. Diagrama de clases

La figura 4-12.3 detalla la estructura genérica del patrón.

images/2figure28-3.png

Figura 4-12.3 - Estructura del patrón Visitor

2. Participantes

Los participantes del patrón son los siguientes:

  • Visitante es la interfaz que incluye la firma de los métodos que realizan una funcionalidad en un conjunto de clases. Existe un método para cada clase que recibe como argumento una instancia de esta clase.

  • VisitanteConcreto1 y VisitanteConcreto2 (VisitanteCálculoCosteEmpresa y VisitanteMailingComercial) implementan los métodos que realizan la funcionalidad correspondiente a la clase.

  • Elemento (Empresa) es una clase abstracta súperclase de las clases de elementos. Incluye el método abstracto aceptaVisitante que acepta un visitante como argumento.

  • ElementoConcreto1 y ElementoConcreto2 (EmpresaSinFilial y EmpresaMadre) implementa el método aceptaVisitante que consiste en volver a llamar al visitante a través del método correspondiente de la clase.

3. Colaboraciones

Un cliente que utiliza un visitante debe en primer lugar crearlo como instancia de la clase de su elección y a continuación pasarlo como argumento al método aceptaVisitante de un conjunto de elementos.

El elemento vuelve a llamar al método del visitante que corresponde con su clase. Le pasa una referencia hacia sí mismo como argumento para que el visitante pueda acceder a su estructura interna....

Dominios de aplicación

El patrón se utiliza en los casos siguientes:

  • Es necesario agregar numerosas funcionalidades a un conjunto de clases sin volverlas pesadas.

  • Un conjunto de clases poseen una estructura fija y es necesario agregarles funcionalidades sin modificar su interfaz.

Si la estructura del conjunto de clases a las que es necesario agregar funcionalidades cambia a menudo, el patrón Visitor no se adapta bien. En efecto, cualquier modificación de la estructura implica una modificación de cada visitante, lo cual puede tener un coste elevado.

Ejemplo en C#

Retomamos el ejemplo de la figura 4-12.2. A continuación se muestra el código de la clase Empresa escrita en C#. El método aceptaVisitante es abstracto pues su código depende de la subclase.

using System; 
 
public abstract class Empresa 
{ 
    public string nombre { get; protected set; } 
    public string email { get; protected set; } 
    public string direccion { get; protected set; } 
 
    public Empresa(string nombre, string email, string direccion) 
    { 
        this.nombre = nombre; 
        this.email = email; 
        this.direccion = direccion; 
    } 
 
    public abstract bool agregaFilial(Empresa filial); 
 
    public abstract void aceptaVisitante(Visitante visitante); 
} 

El código fuente de la subclase EmpresaSinFilial aparece a continuación. El método aceptaVisitante vuelve a llamar al método visita del visitante.

using System; 
 
public class EmpresaSinFilial : Empresa 
{ 
    public EmpresaSinFilial(string nombre, string email, 
    string direccion) : base(nombre, email, direccion) { } 
 
    public override void aceptaVisitante(Visitante visitante) 
    { 
        visitante.visita(this); 
    } 
 
    public...