Strategy Design Pattern

The Strategy design pattern helps to define different behaviors or functionalities that can be changed at runtime.

In the Strategy pattern, we create different classes that represent strategies and that we can use, according to some variation or input.

What are the elements of the Strategy design pattern?

The Strategy pattern consists of a Strategy interface that defines the different specific classes with the strategy implemented and the context in which the strategy to use is established according to some condition, rule or input.

The components of the Strategy pattern are:

  • Interface Strategy: is the interface that defines how the strategy contract will be shaped.
  • Specific Classes Strategy: these are the classes that implement the interface and where the functionality is developed.
  • Context: this decides what strategy will be used.

Strategy Pattern

How a Strategy design pattern is created

We talked before that the goal of the Strategy pattern is to divide functionalities into strategies.

This allows you to focus on a particular problem and solve it and, then decide what solution should be used for a particular case.

Strategy Pattern

We need to think about what will be the common method or function for all the strategies that will go into the interface. From there, you realize the particular implementations.

With an example, it looks simpler. Let’s look at an example of the Strategy pattern with Java.

We are going to use a basic example to explain the Strategy pattern.

So suppose this business logic:

We have different commissions that are paid according to a sale amount.

If the sale amount is higher, a higher commission is paid.

We define the Strategy interface from which we will create specific strategies for each case.


package patterns.strategy;

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

We think about the implementation of each Strategy.

Implementation for a full commission payment.


package patterns.strategy;

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

Implementation for a normal commission payment.


package patterns.strategy;

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

Implementation for a regular commission payment.


package patterns.strategy;

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

We create the context for strategies.


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);
    }
}

We tested the strategy with different sales amounts.


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;
    }
}

output


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

What did we do in the previous code?

Above, we see that for a sale of 1000 our business rules decide to use FullCommission strategy.

Similarly, for sales of 500 and 100 Normal and Regular strategies are decided respectively.

The getStrategy method will decide the strategy to use based on the amount.

This strategy will then be established in context and used to calculate the resulting commission.

  • We decide the strategy to use, according to some input.
  • We define strategy in context.
  • We use context to determine the result.

Conclusion

We saw how to create a Strategy pattern which helps us define different functionalities or algorithms on some common theme by solving and choosing the right one at runtime.

You can review this code GitHub

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

See also