Observer Pattern en sistemas de eventos

Clase 23 de 27Curso de Patrones de Diseño y SOLID en Python

Resumen

Aprende a aplicar el Observer Pattern para lograr gestión flexible de suscripciones y actualización automática ante eventos. Ideal cuando necesitas un servicio de notificación en sistemas con múltiples receptores, con una estructura clara: manager, listeners y un método update que centraliza la reacción a cambios.

¿Qué es el patrón observer y para qué sirve?

El Observer Pattern es un patrón de diseño de comportamiento que resuelve la notificación de eventos a múltiples interesados sin acoplarlos entre sí. Se utiliza para implementar un servicio de eventos simple y efectivo, ampliamente adoptado por su practicidad y facilidad.

¿Cómo se organiza la arquitectura con listeners y manager?

  • Clase manager: agrega, remueve y notifica a todos los listeners.
  • Interfaz listener: define el método update(evento: cualquier tipo).
  • Implementaciones de listener: servicios como email y login que reaccionan en su método update.
  • Clase principal: incluye al manager como atributo; por ejemplo, un servicio de pagos que llama a notifyAll cuando hay que notificar.

¿Cuándo aplicarlo en sistemas de eventos?

Se recomienda cuando: - Un cambio debe notificar a múltiples objetos de forma automática. - Se implementa un sistema de eventos con receptores independientes. - Se necesitan mecanismos de suscripción y notificación simples y claros.

¿Qué beneficios inmediatos aporta?

  • Gestión flexible de suscripciones y receptores.
  • Actualización automática ante nuevos eventos.
  • Simplicidad en la integración de nuevos listeners.

¿Cómo implementarlo paso a paso?

Aplica esta secuencia mínima: - Define una interfaz Listener con un método de notificación: update(evento). - Crea una clase manager que gestione listeners: agregar, remover y notifyAll. - Agrega el manager como atributo de la clase de alto nivel (por ejemplo, el servicio de pagos) y úsalo para notificar.

// 1) Interfaz Listener
interface Listener {
  update(event: any): void;
}

// 2) Clase manager (gestiona suscriptores y notificaciones)
class EventManager {
  private listeners: Listener[] = [];

  add(listener: Listener): void {
    this.listeners.push(listener);
  }

  remove(listener: Listener): void {
    this.listeners = this.listeners.filter(l => l !== listener);
  }

  notifyAll(event: any): void {
    this.listeners.forEach(l => l.update(event));
  }
}

// Implementaciones de Listener (servicios que reaccionan al evento)
class EmailListener implements Listener {
  update(event: any): void {
    // Lógica de notificación por email.
  }
}

class LoginListener implements Listener {
  update(event: any): void {
    // Lógica relacionada con login.
  }
}

// 3) Clase de alto nivel con el manager como atributo (servicio de pagos)
class PaymentsService {
  private manager = new EventManager();

  constructor() {
    this.manager.add(new EmailListener());
    this.manager.add(new LoginListener());
  }

  procesarPago(): void {
    // ... lógica de pago.
    this.manager.notifyAll(/* evento */ undefined);
  }
}

¿Qué habilidades y conceptos refuerza?

  • Uso de interfaces y clases para contratos claros.
  • Diseño de sistemas de eventos con suscripción y notificación.
  • Implementación de listeners como servicios: email y login.
  • Estructuración de una clase de alto nivel con atributo manager y método notifyAll.

¿Has aplicado el patrón Observer en tus proyectos? Compártelo en comentarios y cuéntanos tu caso de uso.