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