Observer en sistemas de pagos con Python
Clase 24 de 27 • Curso de Patrones de Diseño y SOLID en Python
Contenido del curso
Principios SOLID
- 2

Principio de responsabilidad única en SOLID
05:59 min - 3

Refactorizando código Python con principios SOLID
11:14 min - 4

Cómo aplicar SRP en un procesador de pagos con Stripe
25:19 min - 5

Open Closed Principle: extensión sin modificación
02:39 min - 6

Cómo usar clases abstractas en Python
14:46 min - 7

Principio de Liskov en S.O.L.I.D.
03:18 min - 8

Principio de sustitución de Liskov en Python
06:38 min - 9

Interface Segregation: cuándo separar contratos
02:33 min - 10

Segregación de interfaces en procesadores de pagos
09:05 min - 11

Principio de inversión de dependencias explicado
04:13 min - 12

Principio de inversión de dependencias: servicio de pagos flexible
05:56 min
Reestructuración del proyecto
Patrones de Diseño
- 14

Qué son los patrones de diseño: definición y categorías
03:54 min - 15

Strategy Pattern con Python y setprocessor
01:55 min - 16

Strategy Pattern para pagos en Python
10:58 min - 17

Factory Pattern: centralizar creación de objetos
03:05 min - 18

Patrón Factory para procesar pagos con match
11:06 min - 19

Patrón Decorator en 5 pasos para funcionalidad dinámica
03:06 min - 20

Patrón decorador en servicios de pagos
12:57 min - 21

Builder Pattern: construcción paso a paso
01:28 min - 22

Builder pattern para servicios de pagos
18:55 min - 23

Observer Pattern en sistemas de eventos
01:48 min - 24

Observer en sistemas de pagos con Python
Viendo ahora - 25

Chain of Responsibility para validar pagos
02:04 min - 26

Chain of Responsibility en servicios de pagos
16:27 min - 27

Arquitectura robusta para procesadores de pago
03:19 min
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.
# listeners/listener.py
from typing import Protocol, TypeVar
T = TypeVar("T")
class Listener(Protocol[T]):
def notify(self, event: T) -> None:
...
Puntos clave: - 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.py
from dataclasses import dataclass, field
from typing import List, TypeVar
from .listener import Listener
T = TypeVar("T")
@dataclass
class ListenersManager:
listeners: List[Listener[T]] = field(default_factory=list)
def subscribe(self, listener: Listener[T]) -> None:
self.listeners.append(listener)
def unsubscribe(self, listener: Listener[T]) -> None:
self.listeners.remove(listener)
def notify_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.py
from .listener import Listener
class AccountabilityListener(Listener[object]):
def notify(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.
# service_builder.py (fragmento)
from typing import Optional
from listeners.manager import ListenersManager
from listeners.accountability_listener import AccountabilityListener
class ServiceBuilder:
def __init__(self) -> None:
self.listeners: Optional[ListenersManager] = None
def set_listeners(self) -> "ServiceBuilder":
manager = ListenersManager()
accountability = AccountabilityListener()
manager.subscribe(accountability)
self.listeners = manager
return self
En el flujo de pagos, se notifica en una transacción exitosa después de obtener el payment_response dentro de process_transaction:
# dentro del servicio, luego de un pago exitoso
self.listeners.notify_all(f"pago exitoso: {payment_response.transaction_id}")
Sugerencia pendiente: notificar también el pago fallido cuando el payment_response lo indique.
¿Qué habilidades y keywords se refuerzan en esta implementación?
La construcción refuerza conceptos de diseño y tipado en Python que facilitan el mantenimiento y la escalabilidad.
- Patrón Observer: desacopla emisores de eventos y suscriptores.
- Listener como Protocol: interfaz explícita con un único método notify.
- Genéricos (T): eventos de cualquier tipo con tipado estático.
- Listeners Manager: métodos subscribe, unsubscribe, notify_all para orquestación.
- dataclass y field(default_factory=list): inicialización segura de colecciones.
- AccountabilityListener: ejemplo de implementación concreta.
- Módulo listeners con init.py: facilita importaciones limpias.
- Builder: configuración progresiva del service para agregar dependencias como listeners.
- Eventos de dominio: "pago exitoso" y "pago fallido" con datos como transaction_id.
¿Ya resolviste la notificación de pago fallido? Cuéntame en los comentarios cómo lo implementaste y qué diseño elegiste para el evento.