Strategy Pattern para pagos en Python
Clase 16 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
Viendo ahora - 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
11:11 min - 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
Aplicar el patrón estrategia (Strategy Pattern) en un servicio de pagos en Python permite elegir la mejor forma de notificar y cambiarla al vuelo cuando el contexto lo exige. Aquí verás cómo usar un Notifier Protocol para tipar el atributo de notificación de un PaymentService, seleccionar entre EmailNotifier y SMSNotifier según los datos del cliente y cambiar la estrategia en tiempo de ejecución con seguridad.
¿Qué es y cuándo aplicar el strategy pattern en un servicio de pagos?
El patrón se usa cuando hay múltiples estrategias (clases, funciones o algoritmos) que resuelven el mismo problema. Una señal clara: un atributo está tipado como interfaz o protocolo, no como una implementación concreta. En este caso, el atributo es el notificador del PaymentService, tipado como Notifier Protocol, lo que permite intercambiar distintas implementaciones para un mismo objetivo.
- Varias clases implementan una misma interfaz para resolver el mismo caso de uso.
- Un atributo tipado como protocolo/interfaz indica que puedes aplicar el patrón.
- En el contexto: el atributo notificador del PaymentService se tipa con Notifier Protocol.
- La selección se basa en datos del cliente: email o teléfono en su contact info.
- El cambio en tiempo de ejecución se realiza con un método dedicado: set_notifier.
¿Cómo implementar el cambio de estrategia en tiempo de ejecución en Python?
Primero se crea un método que permita modificar la implementación en tiempo de ejecución. Luego, una función elige la estrategia correcta según el caso de uso: si el cliente tiene teléfono, SMS; si tiene email, correo electrónico; si no hay ninguno, se lanza una excepción clara.
¿Cómo se define set_notifier?
from typing import Protocol
class NotifierProtocol(Protocol):
def send(self, message: str) -> None: ...
class PaymentService:
def __init__(self, notifier: NotifierProtocol) -> None:
self.notifier = notifier
def set_notifier(self, notifier: NotifierProtocol) -> None:
self.notifier = notifier
print("Cambiando la implementación del notificador.")
¿Qué hace get_notifier_implementation(customer_data)?
# Imports de dominio (ilustrativos):
# from commons import CustomerData, ContactInfo
# from notifiers import EmailNotifier, SMSNotifier
sms_gateway = None # placeholder para el *gateway* de SMS.
def get_notifier_implementation(customer_data) -> NotifierProtocol:
if customer_data.contact_info.phone:
return SMSNotifier(gateway=sms_gateway)
if customer_data.contact_info.email:
return EmailNotifier()
raise Exception("No se puede elegir la estrategia correcta")
Para probar la selección, puede definirse un generador de datos de ejemplo que devuelva un objeto con nombre y contact info con email o teléfono.
def get_customer_data():
contact_info = ContactInfo(email="john.doe@mail.com", phone=None)
return CustomerData(name="John Doe", contact_info=contact_info)
customer_data = get_customer_data()
notifier = get_notifier_implementation(customer_data)
service = PaymentService(notifier=notifier)
¿Cómo seleccionar y conmutar entre email y SMS según el contexto?
Es útil encapsular la creación de notifiers en funciones pequeñas y reutilizables. Así, si el envío falla, puedes conmutar la estrategia con rapidez usando set_notifier. Si ninguna condición aplica, la función de selección lanza una excepción, lo que también sugiere pensar en una tercera estrategia.
¿Cómo preparar notifiers reutilizables?
def get_email_notifier() -> EmailNotifier:
return EmailNotifier()
def get_sms_notifier() -> SMSNotifier:
return SMSNotifier(gateway=sms_gateway)
email_notifier = get_email_notifier()
sms_notifier = get_sms_notifier()
¿Cómo cambiar de estrategia durante el procesamiento?
service = PaymentService(notifier=notifier)
try:
# Procesar pago y notificar con la estrategia actual.
pass
except Exception:
print("Cambio de estrategia de notificación a estrategia de email")
service.set_notifier(email_notifier)
try:
# Reintentar notificación con email.
pass
except Exception:
service.set_notifier(sms_notifier)
# Reintentar notificación con SMS.
- Strategy Pattern: múltiples implementaciones intercambiables para el mismo problema.
- Notifier Protocol: el atributo notificador se tipa como protocolo para desacoplar.
- Selección de estrategia: get_notifier_implementation elige entre EmailNotifier y SMSNotifier según contact info.
- Cambio en tiempo de ejecución: set_notifier permite sustituir la estrategia tras una excepción.
- Excepción explícita: si no hay email ni teléfono, se lanza "No se puede elegir la estrategia correcta".
- CustomerData y ContactInfo: contienen email y/o phone, base de la decisión.
- EmailNotifier y SMSNotifier: estrategias concretas; SMS puede requerir un gateway.
- Procesador de pagos: se puede aplicar el mismo patrón para seleccionar el processor según el tipo de pago.
Te leo en comentarios: ¿cómo aplicarías el patrón de estrategia para elegir el procesador de pagos según el tipo de pago que recibes?