💡 Ver Caso Práctico: Ejemplo Práctico del Patrón Strategy
Strategy (Estrategia) es un patrón de diseño comportamental que define una familia de algoritmos, encapsula cada uno en una clase separada y los hace intercambiables en tiempo de ejecución.
Propósito y Caso de Uso
Utiliza Strategy cuando tengas múltiples variantes de un mismo algoritmo (formas de calcular envío, de ordenar, de validar, de aplicar descuentos) y quieras evitar un bloque gigante de if/else o switch. El contexto delega el trabajo al objeto estrategia, que puede sustituirse sin tocar el código cliente, respetando Open/ClosedGlosarioSOLIDAcrónimo de cinco principios de diseño orientado a objetos y programación diseñados para hacer que el software sea más comprensible, flexible y mantenible:
S - Single Responsibility Principle (Responsabilidad Única)
O - Open/Closed Principle (Abierto/Cerrado)
L - Liskov Substitution Principle (Sustitución de Liskov)
I - Interface Segregation Principle (Segregación de Interfaz)
D - Dependency Inversion Principle (Inversión de Dependencias)
Ver término completo →.
Estructura del Patrón
- Estrategia (Interfaz): Declara el método común a todos los algoritmos.
- Estrategias Concretas: Implementan variantes específicas del algoritmo.
- Contexto: Mantiene una referencia a una estrategia y delega el trabajo, sin conocer los detalles internos.
Flujo de Funcionamiento
- Selección: El cliente elige e inyecta una estrategia concreta en el contexto.
- Delegación: El contexto invoca el método común, sin saber cuál implementación se ejecuta.
- Sustitución: La estrategia puede cambiarse en cualquier momento, incluso en tiempo de ejecución.
Ejemplos de Implementación Reales
interface ShippingStrategy {
calculate(weightKg: number): number;
}
class StandardShipping implements ShippingStrategy {
calculate(weightKg: number): number { return weightKg * 2; }
}
class ExpressShipping implements ShippingStrategy {
calculate(weightKg: number): number { return weightKg * 5 + 10; }
}
class FreeShipping implements ShippingStrategy {
calculate(): number { return 0; }
}
class ShippingCalculator {
constructor(private strategy: ShippingStrategy) {}
setStrategy(strategy: ShippingStrategy) { this.strategy = strategy; }
cost(weightKg: number): number { return this.strategy.calculate(weightKg); }
}
const calculator = new ShippingCalculator(new StandardShipping());
calculator.cost(3); // 6
calculator.setStrategy(new ExpressShipping());
calculator.cost(3); // 25Cuándo NO usarlo
Si solo hay una o dos variantes que rara vez cambian, un simple if/else es más claro que crear clases adicionales (YAGNIGlosarioYAGNI (You Aren't Gonna Need It)Principio de Extreme Programming (XP) que establece que un programador no debe añadir funcionalidad hasta que sea estrictamente necesario. Su objetivo es evitar la sobre-ingeniería (over-engineering), previniendo código para funcionalidades hipotéticas.Ver término completo →).