Implementa notificaciones de pagos en Python con confianza: aquí verás cómo aplicar el patrón Observer para informar a múltiples sistemas cuando un pago es exitoso o fallido, usando listeners, manager, Protocol, genéricos y el patrón builder para un diseño limpio y extensible.
¿Qué resuelve el patrón observer en el sistema de pagos?
El objetivo es notificar a distintos sistemas ante dos eventos: pago exitoso y pago fallido. Para lograrlo, se define una interfaz de listener con un método único, notify, y un manager que centraliza la suscripción, desuscripción y la propagación del evento a todos los listeners interesados.
Interfaz mínima y clara: un solo método notify que recibe un evento genérico de tipo T.
Gestión centralizada: un Listeners Manager con métodos subscribe, unsubscribe y notify_all.
Extensibilidad: agregar nuevos listeners es simple y no rompe el código existente.
Integración con el servicio: el builder configura el manager y sus listeners al construir la clase principal.
¿Cómo se implementa el patrón observer paso a paso?
A continuación, una guía práctica basada en el código explicado.
¿Cómo se define la interfaz listener con Protocol y genéricos?
Se crea una carpeta listeners/ y un archivo listener.py que declara el Protocol con un genérico T y el método notify.
Uso de typing.Protocol para definir la forma del listener.
Genérico T para aceptar cualquier tipo de evento sin perder tipado.
El método requiere self y no retorna valor.
¿Cómo gestionar suscripciones con un manager usando dataclass?
Se crea manager.py con un atributo lista de listeners y tres métodos: subscribe, unsubscribe y notify_all. La lista se inicializa vacía con field(default_factory=list).
# listeners/manager.pyfrom dataclasses import dataclass, field
from typing import List, TypeVar
from.listener import Listener
T = TypeVar("T")@dataclassclassListenersManager: listeners: List[Listener[T]]= field(default_factory=list)defsubscribe(self, listener: Listener[T])->None: self.listeners.append(listener)defunsubscribe(self, listener: Listener[T])->None: self.listeners.remove(listener)defnotify_all(self, event: T)->None:for listener in self.listeners: listener.notify(event)
Puntos clave:
dataclass simplifica la construcción de la clase.
default_factory=list evita pasar la lista por parámetro y previene listas mutables compartidas.
notify_all itera y llama a notify en cada listener suscrito.
¿Cómo crear un listener concreto para contabilidad?
Se implementa un listener sencillo, por ejemplo, AccountabilityListener, que imprime el evento recibido.
# listeners/accountability_listener.pyfrom.listener import Listener
classAccountabilityListener(Listener[object]):defnotify(self, event:object)->None:print("Notificando el evento:", event)
Puntos clave:
Implementa notify con la lógica específica (aquí, un print controlado).
El tipo de evento puede ajustarse según el dominio.
¿Cómo integrarlo en el servicio con el patrón builder?
Se agrega al service un atributo de tipo ListenersManager y un método del builder para configurarlo y suscribir listeners por defecto.