Cuando desarrollamos aplicaciones en Java, a menudo nos encontramos con situaciones en las que necesitamos cambiar el comportamiento de una clase sin modificar su código fuente. Para resolver este problema de manera elegante y flexible, podemos utilizar el patrón de diseño Strategy.
El patrón Strategy es un patrón de diseño comportamental que permite definir una familia de algoritmos, encapsularlos en clases separadas y hacerlos intercambiables en tiempo de ejecución. Esto evita el uso de estructuras condicionales complejas (como if-else o switch) y favorece el principio de abierto/cerrado (Open/Closed Principle) de SOLID.
En términos simples, en lugar de escribir diferentes comportamientos en una sola clase, delegamos la ejecución del comportamiento a diferentes clases (estrategias) que pueden cambiar dinámicamente.
Supongamos que estamos desarrollando un sistema de pagos para un e-commerce en Java. Queremos permitir distintos métodos de pago como tarjeta de crédito, PayPal y criptomonedas, pero sin acoplar la lógica de pago a la clase principal.
Veamos cómo aplicar el patrón Strategy para solucionar esto. 🛒
Creamos una interfaz que represente la estrategia de pago:
// Interfaz Strategy
public interface MetodoPago {
void pagar(double cantidad);
}
Cada método de pago implementará esta interfaz con su propia lógica.
Ahora, creamos diferentes clases para cada método de pago:
// Estrategia de pago con tarjeta de crédito
public class PagoTarjetaCredito implements MetodoPago {
private String numeroTarjeta;
public PagoTarjetaCredito(String numeroTarjeta) {
this.numeroTarjeta = numeroTarjeta;
}
@Override
public void pagar(double cantidad) {
System.out.println("Pagando $" + cantidad + " con tarjeta de crédito: " + numeroTarjeta);
}
}
// Estrategia de pago con PayPal
public class PagoPayPal implements MetodoPago {
private String email;
public PagoPayPal(String email) {
this.email = email;
}
@Override
public void pagar(double cantidad) {
System.out.println("Pagando $" + cantidad + " con PayPal (cuenta: " + email + ")");
}
}
// Estrategia de pago con criptomonedas
public class PagoCripto implements MetodoPago {
private String direccionWallet;
public PagoCripto(String direccionWallet) {
this.direccionWallet = direccionWallet;
}
@Override
public void pagar(double cantidad) {
System.out.println("Pagando $" + cantidad + " con criptomonedas a la dirección: " + direccionWallet);
}
}
Cada una de estas clases implementa la interfaz MetodoPago, permitiendo que los pagos se realicen de manera independiente.
Ahora, creamos una clase ProcesadorPago que actuará como contexto, permitiéndonos cambiar de estrategia dinámicamente:
// Contexto que usa una estrategia de pago
public class ProcesadorPago {
private MetodoPago metodoPago;
public void setMetodoPago(MetodoPago metodoPago) {
this.metodoPago = metodoPago;
}
public void procesarPago(double cantidad) {
if (metodoPago == null) {
System.out.println("Error: No se ha seleccionado un método de pago.");
} else {
metodoPago.pagar(cantidad);
}
}
}
Finalmente, implementamos el main para probar nuestro diseño:
public class Main {
public static void main(String[] args) {
ProcesadorPago procesadorPago = new ProcesadorPago();
// Pagar con tarjeta de crédito
procesadorPago.setMetodoPago(new PagoTarjetaCredito("1234-5678-9101-1121"));
procesadorPago.procesarPago(100.50);
// Cambiar a PayPal
procesadorPago.setMetodoPago(new PagoPayPal("usuario@example.com"));
procesadorPago.procesarPago(200.75);
// Cambiar a criptomonedas
procesadorPago.setMetodoPago(new PagoCripto("1A2B3C4D5E6F"));
procesadorPago.procesarPago(300.25);
}
}
Pagando $100.5 con tarjeta de crédito: 1234-5678-9101-1121
Pagando $200.75 con PayPal (cuenta: usuario@example.com)
Pagando $300.25 con criptomonedas a la dirección: 1A2B3C4D5E6F
Como puedes ver, podemos cambiar el método de pago dinámicamente sin modificar la clase ProcesadorPago, lo que nos da una gran flexibilidad y facilita la escalabilidad.
✅ Elimina estructuras condicionales complejas (if-else, switch-case).
✅ Facilita la extensión: agregar una nueva estrategia solo requiere una nueva clase.
✅ Permite cambiar el comportamiento en tiempo de ejecución.
✅ Cumple con los principios SOLID: especialización y separación de responsabilidades.
El patrón Strategy en Java es una herramienta poderosa para manejar múltiples algoritmos o comportamientos sin acoplar el código. Al aplicarlo en nuestro sistema de pagos, logramos una solución flexible, extensible y mantenible. 🎯
Si te gustó este artículo, ¡compártelo con otros desarrolladores! 🚀💡
Jorge García
Fullstack developer