Imagina que estás diseñando el sistema para administrar las actividades de una escuela: clases, alumnos, etcétera. Parece sencillo, hasta que te indican que cuando una tarea es marcada en una clase, se le debe notificar a los alumnos la información de ésta. Iterar sobre todos los alumnos que asisten a una clase e ir informando uno por uno sobre la tarea no parece ideal: es por eso que recurrimos al patrón Observer (Observador, en español).

¿Qué es el patrón de diseño Observer?

Todo patrón de diseño está encargado de modelar una situación común a la hora de programar, de forma que el desarrollador en turno no necesite, cuando se encuentre en tal situación, realizar todo de nuevo ("reinventar la rueda", en el lenguaje coloquial). El patrón Observer se implementa cuando on objeto (en nuestro caso, un alumno) requiere estar informado sobre los cambios que suceden en otro objeto (en nuestro caso, las tareas de la clase). El mismo patrón de diseño puede aplicarse en la relación entre un usuario de alguna red social y su bandeja de notificaciones, por ejemplo. Si alguna vez has utilizado addEventListener en JavaScript o estás familizarizado con el modelo Publish Subscribe, este patrón de diseño será fácil de comprender.

Formalmente, el patrón de diseño Observer cuenta con varios elementos (la figura lo ilustra muy bien). Sin embargo, en esta publicación vamos a detallar los dos más importantes: Observer y Subject.

Patrón Observer completo. Ilustración tomada del libro Learning JavaScript Design Patterns, de Addy Osmani

Observer

Este objeto desea estar informado de los cambios en otros objeto (Subject, mostrado a continuación). Sólo posee una función:

  • update(): Esta función es llamado cada vez que ocurre un cambio en el objeto que el Observer está vigilando. El comportamiento de la función depende totalmente del contexto, pero siempre se le pasa como argumento un objeto "context" que indica todo acerca del cambio que ocurrió. En nuestro caso, el contexto serán los datos de la tarea asignada y el comportamiento será imprimir mensajes en pantalla.

Subject

Este objeto es vigilado por varios Observers, y guarda una referencia a cada uno de ellos (generalmente a través de un array). Posee tres funciones:

  • add:  Añade una instancia de Observer a la lista de objetos que revisan el Subject.
  • remove: Remueve un objeto Observer de la lista de objetos que revisan el Subject.
  • notify: Esta función realiza la magia. Itera sobre el array que guarda las referencias a todos los Observers, llamando la función update() de cada uno, dando a conocer que ocurrió un cambio en el Subject.

Implementando el patrón de diseño

Primero, habrá que crear dos clases: Observer y Subject.

Después habrá que diseñar dos clases más: ClassAssigments (desde donde se publicarán todas las tareas de una clas) y Student (cuyo comportamiento al asignarse una nueva tarea será imprimir en pantalla un mensaje).

Instanciamos dos alumnos y una clase

En nuestro primer ejemplo, Luis está inscrito a la clase de Historia y al ejecutar el código, vemos que recibió la notificación de la tarea asignada por el profesor.

En otro ejemplo, Luis ya no está inscrito a la clase (debido a que se graduó), y en su lugar tenemos a Andrés, el cual también recibe las notificaciones sobre las tareas (notemos que Luis ya no las recibe)

¡Y eso es todo! Este ejemplo fue sencillo y no implementamos todo el patrón en su totalidad, pero podemos mejorarlo. Para esto recomiendo leer el libro Learning JavaScript Design Patterns, escrito por Addy Osmani y de la editorial O'Reilly, o el libro Mastering JavaScript Design Patterns, escrito por Tomás Corral y de la editorial Packet. ¡Hasta la próxima!