Observador

RECU-0196 (Recurso Patrón)

Descripción

Este patrón define una dependencia del tipo uno-a-muchos entre objetos, de manera que cuando uno de los objetos cambia su estado, el Observador se encarga de notificar este cambio a resto de los objetos dependientes. El objetivo de este patrón es desacoplar la clase de los objetos clientes del objeto, aumentando la modularidad del lenguaje, así como evitar bucles de actualización.

Nombre

También conocido como Observer , Dependents

Clasificación

Patrón de comportamiento

Motivación

Es necesario mantener la consistencia entre objetos relacionados sin aumentar el acoplamiento de las clases. Si imaginamos la relación entre la capa de presentación de un interfaz de usuario y los datos subyacentes en una representación gráfica observamos rápidamente qué pretende solucionar este patrón.

La interpretación en diferentes diagramas de un conjunto de datos depende de los datos de los objetos. Cualquier modificación en los mismos produce un efecto en la representación. El patrón observador establece las relaciones entre los cambios del sujeto y su efecto posterior.

Aplicabilidad

  • Cuando una abstracción tiene dos aspectos dependientes el uno del otro. Encapsular los aspectos en objetos distintos permite cambiarlos y reutilizarlos.
  • Cuando cambiar un objeto implica cambiar otros pero no conocemos el número exacto a cambiar.
  • Cuando un objeto debe ser capaz de notificar algo a otros sin hacer suposiciones sobre quienes son dichos objetos. Es decir, cuando se quiere bajo acoplamiento.

Estructura

El modelo gráfico del patrón es el siguiente:

Participantes

  • Observador: Define la interfaz de los objetos a los que hay que notificar cambios del Sujeto.
  • ObservadorConcreto: Mantiene una relación con un SujetoConcreto. Mantiene el estado del SujetoConcreto que le es de interes. Implementa Observador para mantener su estado coherente con el del Sujeto.
  • Sujeto: Conoce a sus observadores. Tiene una interfaz para ir añadiendo y eliminando observadores.
  • SujetoConcreto: Envía notificaciones a sus observadores cuando su estado cambia.

Colaboraciones

SujetoConcreto notifica a sus observadores cualquier cambio que se produzca. Una vez notificado el cambio, el ObservadorConcreto puede notificar al Sujeto el mismo, actualizando el estado en el SujetoConcreto.

Consecuencias

  • Permite modificar Sujetos y Observadores de manera independiente.
  • Permite reutilizar un Sujeto sin reutilizar sus Observadores, y viceversa.
  • Permite añadir Observadores sin tener que cambiar el Sujeto ni demás Observadores.
  • Acoplamiento abstracto entre el Sujeto y el Observador. El Sujeto no sabe la clase concreta de sus Observadores.
  • Soporte para Broadcast. El Sujeto envía la notificación a todos los Observadores adscritos . Se pueden ir añadiendo o eliminando Observadores.
  • Actualizaciones inesperadas. Una operación puede provocar cambios en sus Observadores. El protocolo no ofrece detalles sobre lo que ha cambiado.

Implementación

Se deben considerar los siguientes aspectos para la implementación del patrón:

  • Correspondencia entre Sujetos y Observadores: Usualmente el Sujeto guarda una referencia a sus Observadores. En el caso de muchos Sujetos y pocos Observadores es recomendable el uso de una tabla Hash.
  • Observar más de un Sujeto. Es necesario extender la interfaz de actualización para el Observador sepa qué Sujeto manifestó el cambio
  • ¿Quién dispara la actualización mediante llamada a notificación? Se puede realizar de dos maneras. El Sujeto puede hacerlo desde los métodos que cambian de estado, lo que permite desacoplarlo del cliente pero es poco eficiente si hay varios cambios de estados consecutivos. También se puede llamar a la notificación desde el cliente,  delegando en él la responsabilidad de la llamada a notificación
  • Referencias perdidas a Sujetos eliminados. Ee pueden eliminar Sujetos si notificamos qué elementos se eliminan a sus Observadores. Asegurar la consistencia de un Sujeto previamente al envío de una notificación.
  • Simplicar las actualizaciones. Hacer que el método actualizar solo controle los aspectos del Sujeto que sean interesantes.

Código de ejemplo

interface AlarmListener { public void alarm(); }
class SistemaSensor {
   private java.util.Vector listeners = new java.util.Vector();
   public void registro( AlarmListener al ) { listeners.addElement( al ); }
   public void suenaLaAlarma() {
      for (java.util.Enumeration e=listeners.elements(); e.hasMoreElements(); )
         ((AlarmListener)e.nextElement()).alarm();
}  }
class Encendido implements AlarmListener {
   public void alarm() { System.out.println( "Encender Luces" ); }
}
class Puertas implements AlarmListener {
   public void alarm() { System.out.println( "Cerrar Puertas" ); }
}
class Comprobador {
   public void porLosNumeros() { 
      localiza();
      analiza();
      identifica(); }
   protected void localiza() {
      System.out.println( "   establece un perimetro" ); }
   protected void analiza()  {
      System.out.println( "   analiza el perimetro" ); }
   protected void identifica() {
      System.out.println( "   identifica la fuente" ); }
}
                  
class Supervivencia extends Comprobador implements AlarmListener {
   public void alarm() {
      System.out.println( "Supervivencia - por los numeros:" );
      porLosNumeros(); }
   protected void analiza() { System.out.println( "   en marcha las camaras" ); }
}
public class ClassVersusInterface {
   public static void main( String[] args ) {
      SistemaSensor s = new SistemaSensor();
      ss.registro( new Puertas()        );
      ss.registro( new Encendido()     );
      ss.registro( new Supervivencia() );
      ss.suenaLaAlarma();
}  }

La salida sería:

puertas cerradas
encendido luces
Supervivencia - por los números
   establece un perímetro
   marcha las cámaras
   identifica la fuente

Usos conocidos

  • java.util.observer
  • Frameworks de interfaces gráficas orientados a objetos.

Patrones relacionados

  • Singleton: El manejador de cambios puede usar el patron Singleton para convertirlo en instancia única.

Contenidos relacionados

Recursos
Área: Desarrollo » Patrones de Diseño
Código Título Tipo Carácter
RECU-0013 Patrones de diseño Ficha Recomendado
RECU-0202 Singleton Patrón Recomendado