Patrones de diseño: patrón Observador

PrismáticosEl patrón Observador es un patrón fácil de entender, y fácil de ver cuando se necesita. Esta clasificado como un patrón de comportamiento.

El contexto de este patrón es cuando tenemos varios objetos observadores y un objeto observado por los observadores. Los observadores necesitan saber cuando se produce un cambio en el objeto observado. El primer planteamiento que se puede pensar, es que haya un proceso/thread/tarea/… que se encargara de que los observadores vayan haciendo peticiones periódicamente el estado del objeto observado, para así detectar cuando sucede el cambio.

El problema surge cuando el intervalo entre petición es muy corto, o hay demasiados objetos observadores haciendo peticiones al objeto observado, o es necesario que el observador sea notificado inmediatamente después del cambio del objeto observado.

La solución que se aplicaría usando el patrón Observador, trata de que los objetos observadores se añadan a una lista de objetos, y el objeto observado notificará el cambio a todos los objetos de esta lista cuando se produzca el cambio. De esta manera, se produce un cambio de papeles: el observador que tenía la tarea de estar pendiente del cambio, ahora esta a la espera de que el observador le avise. Vamos a intentar detallarlo:

  • el objeto observador necesita ser notificado de los cambios de un objeto observado.
  • el objeto observador se añade a la lista de objetos a notificar, de ese objeto observado.
  • en el objeto observado se produce un cambio.
  • el objeto observado recorre la lista de objetos observadores apuntados, y les va notificando el cambio.

Bajando al lenguaje de programación, se puede conseguir esta relación con una interface y una clase abstracta:

  • Interface Observador:
    • notificar(): los objetos observadores necesitan una función, que será la ejecutada desde el objeto Observado cuando se produzca un cambio.
  • Clase abstracta Observado:
    • observadores: lista de los objetos Observadores añadidos.
    • registrarObservador(Observador): añade el objeto Observador a la lista de objetos a notificar cuando se produzca el cambio.
    • borrarObservador(Observador): elimina el objeto Observador de la lista.
    • notificarObservadores(): recorre los objetos Observadores de la lista, para llamarles a su función notificar().

Ahora, solo debemos heredar y implementar, personalizando según nuestras necesidades. El esquema UML resultante sería similar al siguiente:

Patrón Observador

El resultado final, es que los objetos observadores no hacen ninguna petición mientras nada cambie.  Cuando se produce un cambio, son notificados de que se ha producido el cambio. La función notify() del objeto observador se puede programar de dos maneras:

  • cuando es ejecutada, realizan la petición al objeto observado para saber el cambio hecho.
  • cuando es ejecutada, recibe un parámetro del objeto observado, con el cambio hecho.

Ya depende del contexto. Se ve claramente que la primera opción requiere de una petición extra.

Actualización 2010-02-03: Añado un diagrama de secuencia del proceso en que dos observadores se añaden a la lista de objetos del observado, y después son avisados.

10 comentarios en “Patrones de diseño: patrón Observador

  1. Excelente explicacion!.. simple y clara!.. mejor que otras que hay dando vuelta en la web!
    gracias

  2. Ojalá y todos en internet explicaran las cosas aunque sea la mitad de bien, claro y preciso, de como se explican aquí, antes de leer, este post, estaba totalmente perdido en el tema, pese a que había leído varios artículos al respecto y había visto varios ejemplos, pero ahora, gracias a ustedes he aclarado por completo mis dudas, y me siento hasta en condiciones de poderle explicar yo mismo a otras personas. Realmente, muchas felicidades al autor(es), y esperemos que sigan asi.
    Gracias.
    saludos.

  3. Buen post, pero y el codigo?? no solo con teoria se aprende no se si puedas poner un ejemplo con codigo y consulta la una base de datos con wcf

  4. ver como se trabaja ingresando datos (no codigo) al patron observer al diagrama

  5. solicito saber como ingreasr datos al patron observer (no codigo) o un ejemplo de diagrama usando observer

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *

Puedes usar las siguientes etiquetas y atributos HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>