¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. 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 Observer
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 Observer

Descripción

El patrón Observer tiene como objetivo construir una dependencia entre un sujeto y los observadores de modo que cada modificación del sujeto sea notificada a los observadores para que puedan actualizar su estado.

Ejemplo

Queremos actualizar la visualización de un catálogo en tiempo real. Cada vez que la información relativa a un vehículo se modifica, queremos actualizar la visualización de la misma. Puede haber varias visualizaciones simultáneas.

La solución recomendada por el patrón Observer consiste en establecer un enlace entre cada vehículo y sus vistas para que el vehículo pueda indicarles que se actualicen cuando su estado interno haya sido modificado. Esta solución se ilustra en la figura 4-8.1.

images/figure24-1.png

Figura 4-8.1 - El patrón Observer aplicado a la visualización de vehículos

El diagrama contiene las cuatro clases siguientes:

  • Sujeto es la clase abstracta que incluye todo objeto que notifica a los demás objetos de las modificaciones en su estado interno.

  • Vehículo es la subclase concreta de Sujeto que describe a los vehículos. Gestiona dos atributos: descripción y precio.

  • Observador es la interfaz de todo objeto que necesite recibir las notificaciones de cambio de estado provenientes de los objetos a los que se ha inscrito previamente.

  • VistaVehículo es la subclase concreta correspondiente a la implementación de Observador cuyas instancias muestran la información de un vehículo. 

El funcionamiento es el siguiente: cada nueva vista se inscribe como observador de su vehículo mediante el método agrega. Cada vez que la descripción...

Estructura

1. Diagrama de clases

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

images/figure24-3.png

Figura 4-8.3 - Estructura del patrón Observer

2. Participantes

Los participantes del patrón son los siguientes:

  • Sujeto es la clase abstracta que incluye la asociación con los observadores así como los métodos para agregar o suprimir observadores;

  • Observador es la interfaz que es necesario implementar para recibir las notificaciones (método actualiza);

  • SujetoConcreto (Vehículo) es una clase correspondiente a la implementación de un sujeto. Un sujeto envía una notificación cuando su estado se ha modificado;

  • ObservadorConcreto (VistaVehículo) es una clase de implementación de un observador. Mantiene una referencia hacia el sujeto e implementa el método actualiza. Solicita a su sujeto información que forma parte de su estado durante las actualizaciones invocando al método getEstado

3. Colaboraciones

El sujeto notifica a sus observadores cuando su estado interno ha sido modificado. Cuando un observador recibe esta notificación, se actualiza en consecuencia. Para realizar esta actualización, puede invocar a los métodos del sujeto que dan acceso a su estado.

Dominios de aplicación

El patrón se utiliza en los casos siguientes:

  • Una modificación en el estado de un objeto genera modificaciones en otros objetos que se determinan dinámicamente.

  • Un objeto quiere avisar a otros objetos sin tener que conocer su tipo, es decir sin estar fuertemente acoplado a ellos.

  • No se desea fusionar dos objetos en uno solo.

Ejemplo en C#

Retomamos el ejemplo de la figura 4-8.1. El código fuente de la clase Sujeto aparece a continuación. Los observadores se gestionan mediante una lista.

using System.Collections.Generic; 
 
public abstract class Sujeto 
{ 
    protected IList<Observador> observadores = 
        new List<Observador>(); 
 
    public void agrega(Observador observador) 
    { 
        observadores.Add(observador); 
    } 
 
    public void suprime(Observador observador) 
    { 
        observadores.Remove(observador); 
    } 
 
    public void notifica() 
    { 
        foreach (Observador observador in observadores) 
            observador.actualiza(); 
    } 
} 

El código fuente de la interfaz Observador es muy simple puesto que sólo contiene la firma del método actualiza.

public interface Observador 
{ 
    void actualiza(); 
} 

El código...