sábado, 29 de diciembre de 2012

Patrón de diseño observer

Es una patrón de diseño que define una dependencia uno a muchos, de tal forma que cuando un objeto cambia de estado se notifica a los objetos dependientes, para que se actualicen automáticamente.

Voy a ilustrarlo con un ejemplo. Imaginemos que tenemos una estación meteorológica y varias personas consultan su estado constantemente aunque la temperatura no cambie. Esto no es muy óptimo y consume recursos (por ejemplo ancho de banda). Lo ideal sería que la estación meteorológica informara a sus observadores cuándo se produzca un cambio en la lectura del sensor de temperatura. Este problema se puede resolver con el patrón observer.

Estructura


Sujeto: interfaz donde se declaran e implementan (si se quiere) los métodos añadir o eliminar observadores. También incluye el método notificar encargado de actualizar los cambios.

SujetoConcreto (estación meteorológica): hereda los métodos añadir y eliminar, además posee los métodos propios, getEstado y setEstado. El método setEstado llama a notificar, que éste a su vez obliga a los observadores a consultar (getEstado) el estado de la estación meteorológica.  También almacena la variable de interés para sus observadores.

Observador: define una interfaz para los objetos a los que se deben notificar cambios en un sujeto.

ObservadorConcreto: implementa el código encargado de consultar el estado del sujeto concreto. Además almacena una copia del estado del sujeto.


Ventajas

  • Reduce el acoplamiento entre clases. Por ejemplo separar la capa de datos de la de presentación.
  • Existe una separación entre sujetos y observadores, lo que permite reutilizarlos de manera independiente.
  • Podemos añadir y quitar observadores sin tener que cambiar el sujeto ni los observadores.

FAQ
  • ¿Quien dispara la actualización?. Dos formas:
    • El sujeto concreto es el que llama al método notificar. Libera al cliente de esta operación. La desventaja es que si hay muchas actualizaciones seguidas, no es óptico y tal vez sea preferible esperar a que se realicen todos los cambios.
    • La clase cliente llama a notificar, cargándose con esa responsabilidad. 
  • ¿Cómo gestionamos la eliminación de un sujeto?
    • Notificando la eliminación a los observadores. Eliminar los observadores del sujeto no es una opción.
  • Diferencia entre el modelo pull y push.
    • Modelo pull: el sujeto envía lo mínimo, los observadores piden lo necesario. Puede ser poco eficiente.
    • Modelo push: el sujeto envía información detallada del cambio, aunque los observadores no la necesiten. Mayor acoplamiento, observadores menos reutilizables.
  • ¿Cómo especificar las notificaciones que nos interesan?
    • En los métodos añadir y actualizar , pasar otro parámetro que lo indique (además del observador y el sujeto respectivamente).

Código ejemplo: Patrón Observer


No hay comentarios:

Publicar un comentario