Patrón de diseño Strategy en Java

El patrón de diseño Strategy ayuda a definir diferentes comportamientos o funcionalidades que pueden ser cambiadas en tiempo de ejecución.

En el patrón Strategy creamos diferentes clases que representan estrategias y que podremos usar según alguna variación o input.

Cuales son las partes del patrón de diseño Strategy

El patrón Strategy está compuesto por una interfaz Strategy de la cual se definen las diferentes clases concretas con la estrategia implementada y el contexto en donde se establece la estrategia a utilizar según alguna condición, regla o input.

Los componentes del patrón Strategy son:

  • Interfaz Strategy: es la interfaz que define cómo se conformará el contrato de la estrategia.
  • Clases Concretas Strategy: son las clases que implementan la interfaz y donde se desarrolla la funcionalidad.
  • Contexto: aquí se decide qué estrategia se usará.

Strategy Pattern

Como se crea el patrón de diseño Strategy

Hablamos antes que el objetivo del patrón Strategy es dividir funcionalidades en diferentes estrategias.

Esto te permite enfocarte en un problema en particular y resolverlo para luego decidir cual es la solución que debe utilizarse para un determinado caso.

Strategy Pattern

Necesitamos pensar bien cuál será el método o función en común para todas las estrategias que irá en la interfaz. A partir de allí realizas la implementaciones particulares.

Con un ejemplo se ve más simple. Veamos un ejemplo del patrón Strategy con Java.

Usaremos un ejemplo muy simple para explicar el patrón Strategy.

Supongamos esta regla de negocio:

Tenemos diferentes comisiones que se pagan según un monto de venta. Si el monto de venta es mayor se paga mayor comisión.

Definimos la interfaz Strategy de la cual crearemos estrategias puntuales para cada caso.


package patterns.strategy;

public interface CommissionStrategy {
    double applyCommission(double amount);
}

Pensamos en las implementaciones de cada Strategy.

Implementación para un pago de una comisión full.


package patterns.strategy;

public class FullCommission implements CommissionStrategy {
    @Override
    public double applyCommission(double amount) {
        // do complicated formula of commissions.
        return amount * 0.50d;
    }
}

Implementación para un pago de una comisión normal.


package patterns.strategy;

public class NormalCommission implements CommissionStrategy {
    @Override
    public double applyCommission(double amount) {
        // do complicated formula of commissions.
        return amount * 0.30;
    }
}

Implementación para un pago de una comisión regular.


package patterns.strategy;

public class RegularCommision implements CommissionStrategy {
    @Override
    public double applyCommission(double amount) {
        // do complicated formula of commissions.
        return amount * 0.10;
    }
}

Creamos el contexto para las estrategias.


package patterns.strategy;

public class Context {

    private CommissionStrategy commissionStrategy;

    public Context(CommissionStrategy commissionStrategy){
        this.commissionStrategy = commissionStrategy;
    }

    public double executeStrategy(double amount){
        return commissionStrategy.applyCommission(amount);
    }
}

Probamos la estrategia con diferentes montos de venta.


package patterns.strategy;

public class StrategyPatternExample {

    public static void main(String[] args) {

        CommissionStrategy commissionStrategy = getStrategy(1000d);
        Context context = new Context(commissionStrategy);
        System.out.println("Commission for 1000d = " + context.executeStrategy(1000d));

        commissionStrategy = getStrategy(500d);
        context = new Context(commissionStrategy);
        System.out.println("Commission for 500d = " + context.executeStrategy(500d));

        commissionStrategy = getStrategy(100d);
        context = new Context(commissionStrategy);
        System.out.println("Commission for 100d = " + context.executeStrategy(100d));
    }

    private static CommissionStrategy getStrategy(double amount) {
        CommissionStrategy strategy;
        if (amount >= 1000d) {
            strategy = new FullCommission();
        } else if (amount >= 500d && amount <= 999d) {
            strategy = new NormalCommission();
        } else {
            strategy = new RegularCommision();
        }
        return strategy;
    }
}

La salida


Commission for 1000d = 500.0
Commission for 500d = 150.0
Commission for 100d = 10.0

Que hicimos en el código previo:

Arriba vemos que para una venta de 1000 nuestras reglas de negocio deciden usar la estrategia FullCommission. Del mismo modo para ventas de 500 y 100 se deciden estrategias Normal y Regular respectivamente.

El método getStrategy decidirá la estrategia a utilizar según el monto.

Luego se establecerá esa estrategia en el contexto y se usará para calcular la comisión resultante.

  • Decidimos la estrategia que corresponde usar según algún input.
  • Definimos la estrategia en el contexto.
  • Usamos el contexto para determinar el resultado.

Conclusión

Vimos cómo crear un patrón Strategy el cual nos ayuda a definir diferentes funcionalidades o algoritmos sobre algún tema común al resolver y elegir el adecuado en tiempo de ejecución.

Puedes descargar este código en github

Hi! If you find my posts helpful, please support me by inviting me for a coffee :)

Ver también