The Strategy Pattern

 Definition

The Strategy Pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.

It helps us to define different behaviors or functionalities that can be changed in execution time. We can create different classes that represent strategies and that we can use according to some input variation.

The strategy pattern is made up of:

  • Strategy interface: the interface that is common to all concrete strategies. 
  • Concrete strategies: classes that are implemented by the interface and where functionality is developed.
  • Context: establishes what strategy it's gonna be used.

Implementation

Let's say that we want to build a simple calculator. In which we would implement an algorithm to add and subtract two numbers.



TDD

Let's start creating some test cases. First, we need to add a test and see if any new test fails, then we update the code to make the test pass, and last we run the code again. In this case, we created a test for the operation method.

    @Test
    public void addsTwoNumbers(){
        Context context = new Context(new Add());
        int add = context.executeStrategy(10, 5);
        assertEquals(add, 15);
    }
    
    @Test
    public void subtractsTwoNumbers(){
        Context context = new Context(new Subtract());
        int add = context.executeStrategy(10, 5);
        assertEquals(add, 5);
    }

Interface OperationStrategy

The strategy interface declares the operation in common.

public interface OperationStrategy {
    int operation(int a, int b);
}

Class Add and Subtract

public class Add implements OperationStrategy{
    @Override
    public int operation(int a, int b) {
        return a + b;
    }
}
public class Subtract implements OperationStrategy{
    @Override
    public int operation(int a, int b) {
        return a - b;
    } 
}

Context

public class Context {
    private OperationStrategy strategy;
    
    Context(OperationStrategy strategy){
        this.strategy = strategy;
    }
    
    public int executeStrategy(int a, int b){
        return strategy.operation(a, b);
    }
}

Client

public static void main(String[] args) {
        Context contextA;
        contextA = new Context(new Add());
        int add = contextA.executeStrategy(10, 5);
        System.out.println(add);
        
        Context contextB;
        contextB = new Context(new Subtract());
        int subtract = contextB.executeStrategy(10, 5);
        System.out.println(subtract);
}


Reference
Head First Design Patterns
by Eric Freeman, Elisabeth Robson, Bert Bates, Kathy Sierra
Released October 2004
Publisher(s): O'Reilly Media, Inc.

Comments