Cuando construimos aplicaciones donde múltiples vistas necesitan reaccionar ante un mismo cambio de datos, la comunicación directa entre clases se vuelve difícil de mantener. Los patrones de comportamiento resuelven exactamente ese problema: delegan la responsabilidad de comunicación entre clases y encapsulan esa lógica, sentando las bases de un estilo de programación más limpio y desacoplado.
¿Qué es la programación reactiva y por qué importa?
La programación reactiva [0:12] es un paradigma donde existe un ente que emite eventos y otro que se suscribe a ellos. No importa si hay uno o miles de suscriptores: cada uno escucha los eventos del emisor y simplemente reacciona. De ahí viene su nombre: reaccionar ante los cambios en lugar de consultarlos manualmente.
Este paradigma es la base sobre la que se construye el patrón Observer, uno de los patrones de comportamiento más utilizados en el desarrollo de software.
¿Cómo funciona el patrón Observer con publish-subscriber?
El patrón Observer [0:38] sigue un modelo conocido como publish-subscriber. En este modelo hay dos roles claramente definidos:
- Observable: el ente que emite datos. Su única responsabilidad es enviar la información a quienes estén suscritos.
- Observer: el ente que escucha. Se suscribe al observable y reacciona cuando recibe una notificación de cambio.
Lo interesante es que los observers pueden suscribirse o desuscribirse en cualquier momento, y para el observable esto es completamente transparente. No le importa cuántos hay ni quiénes son; solo se encarga de notificar.
¿Cuándo se aplica en un proyecto real?
En el contexto del proyecto [1:08], el saldo disponible es un dato que cambia y que necesita reflejarse en múltiples pantallas: la vista de home y la vista de transferencias. Ambas vistas se suscriben al observable del saldo y, cuando este cambia, reaccionan actualizando su interfaz.
¿Cómo se estructura en código Java?
Dentro del paquete de UI se crea un nuevo paquete llamado Observables [1:30]. En él se definen dos interfaces fundamentales:
Interfaz Observable:
java
public interface Observable {
void addObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers(double value);
}
addObserver: registra un nuevo observer para que comience a recibir notificaciones.
removeObserver: elimina un observer existente para que deje de escuchar cambios.
notifyObservers: recorre todos los observers suscritos y les envía el nuevo valor. El parámetro es de tipo double porque en este caso lo que cambia es el saldo disponible [2:29].
Interfaz Observer:
java
public interface Observer {
void notifyChange(double newValue);
}
notifyChange: es el callback [2:45] que se ejecuta cuando el observable informa de un nuevo valor. Cada clase que implemente esta interfaz decidirá cómo reaccionar ante ese cambio.
Es importante notar que Java ya incluye una clase Observer propia [2:03], pero en este caso se crean interfaces personalizadas para comprender a fondo el mecanismo interno del patrón.
¿Qué relación existe entre las dos interfaces?
El flujo completo funciona así:
- El observable mantiene una lista interna de observers.
- Cuando el dato relevante cambia, el observable llama a
notifyObservers con el nuevo valor.
- Cada observer suscrito recibe ese valor a través de
notifyChange y actualiza su vista o lógica según corresponda.
Este diseño permite que las vistas de home y transferencias no dependan directamente una de la otra, sino que ambas dependen del observable del saldo. Eso reduce el acoplamiento y facilita agregar o quitar pantallas sin modificar la lógica de emisión.
Si ya has trabajado con listeners o eventos en otros contextos, el patrón Observer te resultará familiar. La diferencia clave es que aquí se formaliza con interfaces propias, lo que da control total sobre el comportamiento de suscripción y notificación. ¿Has implementado este patrón en algún otro proyecto? Comparte tu experiencia.