El patrón Strategy en 5 minutos: Adiós a los IFs de cálculo
Cuando estás creando una aplicación, es muy común ofrecer distintas formas de hacer una misma cosa: diferentes métodos de pago, formas de calcular un envío o tipos de descuento.
Sin un patrón de diseño, el código suele convertirse en una bola de nieve de condicionales. Hoy vas a aprender a limpiar eso con el patrón Strategy.
1. El problema: Cálculos llenos de condicionales
Imagina que tienes una tienda en línea y debes calcular el costo de envío según la empresa de transporte.
Crea un archivo llamado envios.py en tu terminal:
Python
def calcular_envio(empresa, peso_kg):
if empresa == "dhl":
return peso_kg * 10 + 5 # Tarifa base + peso
elif empresa == "fedex":
return peso_kg * 8 + 12
elif empresa == "olva":
return peso_kg * 5 + 3
else:
raise ValueError("Empresa de envío no válida")
# Probamos el cálculo
costo = calcular_envio("dhl", peso_kg=3)
print(f"Costo de envío: ${costo}")
¿Por qué esto es un dolor de cabeza?
Si la tarifa de DHL cambia, si FedEx lanza una promoción, o si quieres agregar 5 empresas más, tienes que entrar a modificar esta misma función gigante. Un error en un elif rompe el cálculo de todas las demás empresas.
2. La solución: El patrón Strategy
La idea del patrón Strategy es muy simple: cada forma de calcular pasa a ser una "estrategia" independiente. Tu programa principal solo ejecuta la estrategia que le asignes.
Reemplaza tu envios.py por este código:
Python
# 1. Definimos las Estrategias (Algoritmos independientes)
class EnvioDHL:
def calcular(self, peso_kg):
return peso_kg * 10 + 5
class EnvioFedEx:
def calcular(self, peso_kg):
return peso_kg * 8 + 12
class EnvioOlva:
def calcular(self, peso_kg):
return peso_kg * 5 + 3
# 2. El Contexto (El carrito o calculadora de la tienda)
class CalculadoraEnvios:
def __init__(self, estrategia):
# Asignamos la estrategia seleccionada
self.estrategia = estrategia
def obtener_costo(self, peso_kg):
# Ejecuta la estrategia actual sin importarle cuál sea
return self.estrategia.calcular(peso_kg)
# 3. Código principal
# El usuario elige enviar por FedEx
servicio = EnvioFedEx()
calculadora = CalculadoraEnvios(servicio)
costo = calculadora.obtener_costo(peso_kg=3)
print(f"📦 Costo con FedEx: ${costo}")
3. ¿Por qué esto cambia las cosas?
- Cada regla está aislada: Si DHL cambia sus precios, solo modificas la clase
EnvioDHL. Cero riesgo de alterar los precios de FedEx u Olva. - Puedes cambiar de estrategia sobre la marcha:
Python
# Si el cliente cambia de opinión en el carrito:
calculadora.estrategia = EnvioOlva()
print(f"Nuevo costo con Olva: ${calculadora.obtener_costo(3)}")
Tu turno (Reto de 2 minutos)
Imagina que agregas un nuevo servicio de envío rápido en moto llamado EnvioExpress:
- Crea la clase
EnvioExpresscon su métodocalcular(self, peso_kg)que cobre un monto fijo de$15sin importar el peso. - Pásaselo a la
CalculadoraEnviosy calcula el costo.
¡Y listo! Ya dominas dos de los patrones más usados en la industria.