En la entrada del patrón observer, terminábamos con una pregunta.

¿Cómo podemos controlar cuándo se envían las notificaciones?

La respuesta es simple: añadiendo un estado al sujeto que envía las notificaciones mediante una variable. Si esta variable tiene un valor, notificamos a los observadores y la devolvemos a su estado original. En caso contrario no hacemos nada.

Por ejemplo, supongamos que la clase Balanza notifica a sus observadores cuando se ha puesto un peso sobre ella de más de 1000gr. Si no tuviéramos esa variable booleana en cada pesaje tendríamos que recorrer toda la lista, notificando de cualquier pesaje.

Podrías pensar acertadamente que existe cierta complicación en el código. ¿Por que no notificar directamente si se da una condición a los observadores? Bueno, en este ejemplo quizás si sería lo más lógico, pero sirve como excusa para extrapolar a otras situaciones donde las condiciones para notificar sean más complejas.

Aunque controlar las notificaciones no es algo contemplado en el propio patrón observer, la implementación de Java sí que añade por defecto esta posibilidad. Si echamos un vistazo al código de la clase Observable vemos que tiene dos campos: un Vector de objetos Observer y un atributo booleano.

Una herencia envenenada

Que Observable tenga una clase Vector para albergar los Observer puede ser indicativo de una necesaria huida. Pero aprovechemos que estamos aquí para hacer énfasis en el punto clave de esta implementación:

  • Observable es una clase concreta.

Esto implica que para hacer tu patrón Observer con la implementación de Java tienes una limitación: Tu objeto debe heredar de Observable, y si ya extiende otro objeto, no puedes hacer nada. ¿Que pasa si quieres customizar tu objeto Observable? Sigues teniendo que extender la clase. Y si quieres componer un objeto con otro que extienda Observable, olvídate de usar sus métodos para cambiar y leer el estado porque son protected.

Por supuesto esto tiene una explicación y es que estas dos clases, tal y como podéis ver en su documentación, existen desde el JDK 1.0. Por este y otros motivos se recomienda implementar tu propio patrón Observer a través de interfaces.

Puedes encontrar un ejemplo sencillo y comentado de la implementación del patrón observer en mi repositorio de Github.