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:04 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
Strategy Pattern para pagos en Python
Resumen
Seleccionar la estrategia correcta en tiempo de ejecución es una de las ventajas más potentes del Strategy Pattern. En un procesador de pagos construido en Python, esta capacidad permite intercambiar notificadores —correo electrónico o mensaje de texto— sin modificar la clase principal del servicio, manteniendo un diseño flexible y extensible.
¿Cómo se detecta cuándo aplicar el Strategy Pattern?
Una señal clara para aplicar este patrón es cuando un atributo de la clase de alto nivel tiene como tipo de dato una interfaz (o en Python, un protocol) [01:08]. Esto indica que múltiples clases implementan esa interfaz y cada una resuelve un caso puntual con una estrategia diferente.
En el servicio de pagos, la clase PaymentService define su atributo notifier con el tipo NotifierProtocol. Esto significa que cualquier clase que cumpla con ese protocolo puede ocupar ese lugar: un EmailNotifier, un SMSNotifier o cualquier implementación futura.
¿Cuál es el primer paso para implementar la estrategia?
El primer paso es crear un método que permita modificar la implementación de la estrategia en tiempo de ejecución [02:00]. Dentro de PaymentService se define el método set_notifier:
python def set_notifier(self, notifier: NotifierProtocol): self.notifier = notifier print("Cambiando la implementación del notificador")
Este método recibe una instancia que cumpla con NotifierProtocol y reemplaza el notificador actual. Es simple, pero es la pieza que habilita el intercambio dinámico.
¿Cómo se elige la estrategia correcta según el contexto?
El segundo paso consiste en crear una función que seleccione la estrategia adecuada para cada caso de uso [02:38]. En el archivo principal se define get_notifier_implementation, que recibe los datos del cliente y evalúa qué canal de notificación usar:
python def get_notifier_implementation(customer_data: CustomerData) -> NotifierProtocol: if customer_data.contact_info.phone: return get_sms_notifier() elif customer_data.contact_info.email: return get_email_notifier() raise Exception("No se puede elegir la estrategia correcta")
- Si el
contact_infocontiene teléfono, se retorna unSMSNotifier[03:16]. - Si contiene email, se retorna un
EmailNotifier[03:50]. - Si no hay ninguno de los dos, se levanta una excepción porque no existe una estrategia válida [04:12].
¿Cómo se encapsulan las estrategias disponibles?
Cada estrategia se encapsula en su propia función factoría para mantener el código limpio:
python def get_email_notifier() -> EmailNotifier: return EmailNotifier()
def get_sms_notifier() -> SMSNotifier: return SMSNotifier(gateway="sms_gateway_example")
Estas funciones se pueden invocar de forma independiente cuando se necesite cambiar la estrategia manualmente [06:30].
¿Cómo se intercambian estrategias en tiempo de ejecución?
Una vez seleccionada la estrategia inicial, el patrón permite reaccionar ante fallos y cambiar de notificador sin reiniciar el proceso [07:00]. Por ejemplo, si el envío por email falla, se captura la excepción y se cambia a SMS:
python email_notifier = get_email_notifier() sms_notifier = get_sms_notifier()
Estrategia inicial
service.set_notifier(email_notifier)
Si falla el email, cambiar a SMS
try: service.process_payment() except Exception: print("Cambio de estrategia de notificación a SMS") service.set_notifier(sms_notifier)
Este mecanismo ofrece dos beneficios principales:
- Selección contextual: la estrategia se elige automáticamente según los datos del cliente.
- Intercambio dinámico: ante un fallo, se sustituye la estrategia sin alterar la lógica del servicio.
Un detalle interesante es que la excepción lanzada cuando no hay teléfono ni email revela la oportunidad de crear una tercera estrategia [08:08]. Podría ser una notificación push o un registro en base de datos que garantice que el usuario reciba confirmación de su pago.
El mismo principio aplica al procesador de pagos: su atributo también es un protocolo, lo que abre la puerta a seleccionar dinámicamente entre diferentes métodos de pago [08:50]. ¿Cómo implementarías tú el Strategy Pattern para elegir el procesador de pagos correcto según el tipo de transacción? Comparte tu propuesta en los comentarios.