El patrón Observer es posiblemente el más conocido de los patrones de diseño de software, quizás porque es el común denominador de cualquier aplicación gráfica.
Es muy fácil de explicar y se puede resumir en que cuando un objeto A le pasa algo, este se lo notifica a una serie de objetos llamados observadores. Quizás lo difícil sea implementarlo, pero vayamos por partes.
Según la definición tenemos dos tipos de agentes: un sujeto del cambio y un observador y por lo tanto tendremos dos clases: un Sujeto y un Observador.
Sabemos también que el sujeto debe notificar a un observador. Para ello haremos que el sujeto guarde en una lista a todos sus observadores.
¿Pero como lo notifica? Pues simplemente implementaremos un método en los observadores que sea llamado por el objeto observado mediante un bucle foreach.
Pero esto se puede mejorar…¿Como? El comportamiento que hemos visto es extensible para cualquier objeto sujeto a cambio y a sus observadores, por lo tanto, podemos abstraerlo en dos interfaces.
Esta generalización nos permite tener varios observadores u oyentes que hagan distintas cosas cuando el sujeto quiera notificar algo. Hemos desacoplando ambos objetos y ahora el sujeto ya no tiene que saber de qué tipo concreto es su oyente para notificarle un cambio.
¿Pero qué pasa con los observadores?
Como a lo mejor te habrás dado cuenta este diseño deja un poco desvalidas a las clases observadoras. No controlan cuando deben dejar de serlo de una clase ni tienen control ninguno sobre cuándo quieren ser notificadas. No nos preocupemos, si queremos que las clases observadoras tengan el control de suscribirse y desuscribirse a eventos, solo necesitaremos hacer implementar una referencia a la clase que está observando para notificarle sus deseos.
¿Y si una clase solo quiere ser notificada en determinadas circunstancias? Bueno, aprovecharemos para explicar eso mientras vemos la implementación nativa de Java para este patrón en otra entrada.