Patrón Observer en Sistemas de Pago: Implementación y Notificaciones

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

Resumen

¿Cómo implementar el patrón Observer en un sistema de pagos?

Implementar el patrón Observer en un sistema de pagos mejora significativamente la capacidad del sistema para reaccionar a eventos como pagos exitosos y fallidos. Este enfoque nos permite enviar notificaciones automáticas a sistemas relevantes cuando ocurren transacciones específicas. En esta clase, vamos a desglosar cómo configurar este patrón en Python, siguiendo los pasos adecuados para favorecer la escalabilidad y mantenibilidad del código.

¿Cómo se define el protocolo de Listener en Python?

El primer paso para aplicar el patrón Observer es definir el protocolo que actúa como interfaz para los Listeners. En Python, podemos crear este protocolo utilizando el módulo typing.

from typing import Protocol, TypeVar

T = TypeVar('T')

class Listener(Protocol[T]):
    def notify(self, event: T) -> None:
        pass

Este sencillo protocolo obliga a los Listeners concretos a implementar el método notify, el cual tomará un evento de tipo genérico T, no retornando ningún valor.

¿Cómo manejamos los Listeners?

El siguiente paso es crear un manejador de Listeners, que permitirá a los Listeners suscribirse, desuscribirse y recibir notificaciones.

from typing import List
from dataclasses import dataclass, field

@dataclass
class ListenersManager:
    listeners: List[Listener] = field(default_factory=list)

    def subscribe(self, listener: Listener) -> None:
        self.listeners.append(listener)
    
    def unsubscribe(self, listener: Listener) -> None:
        self.listeners.remove(listener)
    
    def notify_all(self, event: T):
        for listener in self.listeners:
            listener.notify(event)

El ListenersManager actúa como el mediador, encargándose de la adición y eliminación de listeners y de la notificación de eventos a todos los listeners suscritos.

¿Cómo implementamos un Listener específico?

Para demostrar el uso práctico del patrón Observer, podemos crear un Listener específico que notifique al sistema de contabilidad sobre pagos exitosos.

from listeners import Listener

class AccountabilityListener(Listener):
    def notify(self, event: T):
        print(f"Notificando al sistema de contabilidad sobre el evento: {event}")

Este AccountabilityListener simplemente imprime un mensaje de notificación al recibir un evento.

¿Cómo se integra el patrón Observer en la clase principal?

Finalmente, debemos adaptar nuestra clase principal para incorporar el ListenersManager y los Listeners específicos que deseamos usar.

from listeners import ListenersManager, AccountabilityListener

class PaymentService:
    def __init__(self):
        self._listener_manager = ListenersManager()
        self._set_listeners()

    def _set_listeners(self):
        accountability_listener = AccountabilityListener()
        self._listener_manager.subscribe(accountability_listener)

    def process_transaction(self, payment_response):
        if payment_response.is_success:
            self._listener_manager.notify_all(f"Pago exitoso: {payment_response.transaction_id}")
        else:
            self._listener_manager.notify_all(f"Pago fallido: {payment_response.transaction_id}")

En este ejemplo, la clase PaymentService se encarga de gestionar los eventos de notificación. Durante una transacción exitosa o fallida, el servicio utiliza ListenersManager para notificar a todos los listeners suscritos.

¿Cuáles son los beneficios de utilizar el patrón Observer?

Utilizar el patrón Observer proporciona varios beneficios:

  • Desacoplamiento: Los emisores de eventos no necesitan conocer los detalles de los listeners.
  • Escalabilidad: Facilita la adición de nuevos listeners sin alterar el código existente.
  • Reusabilidad: Los listeners pueden ser reutilizados en diferentes áreas de la aplicación.

Integrar el patrón Observer en tu sistema de pagos no solo mejora la organización y el flujo del código, sino que también incrementa la eficiencia en la gestión de eventos. ¡Sigue explorando y aprendiendo más sobre patrones de diseño para llevar tu programación al siguiente nivel!