Contents

Design Patterns Days: Strategy

Overview

As the Wikipedia definition says:

The strategy pattern is useful for situations where it is necessary to dynamically swap the algorithms used in an application. The strategy pattern is intended to provide a means to define a family of algorithms, encapsulate each one as an object, and make them interchangeable. The strategy pattern lets the algorithms vary independently from clients that use them.

Or in simpler terms, Instead of hardcoding an implementation that can vary according to the various classes. We on runtime inject the appropriate algorithm/behaviour that the class will need.

Example Scenario

We have a sample Person class,which has the method “run” that has the implementation on how fast a person can run.

Depending on our usecase we can create several subclasses of class Person that will ovverride the run implementation.

But…..

What if the different subclasses want to share the behaviour? Do we copy paste the run method there? What if we need to change the run method to introduce some new changes? We need to go back and change every individual piece of implementation that exists. This is where the strategy pattern can help. Let me show you how.

Code Example

The Person class contains the name of the person and a run behaviour that will be injected during runtime.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22


public interface RunBehaviour {
    public void run();
}


public class Person {

    String name;
    RunBehaviour runBehaviour;

     public Person(String name, RunBehaviour runBehaviour) {
        this.name = name;
        this.runBehaviour = runBehaviour;
    }

    public void run(){
        runBehaviour.run();
    }

}

We now implement the various types of “run” behaviour/algorithm the person can have. Fast Runner/Slow Runner/Speedster.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14

public class FastRunner implements RunBehaviour{
    @Override
    public void run() {
        System.out.println("WHOSHHHH!!!!!! ");
    }
}

public class SlowRunner implements RunBehaviour {
    @Override
    public void run() {
        System.out.println("Barely even a run!!");
    }
}

The implementation for run behaviour is injected to the Person class using constructor injection. During runtime we can create the type of person we intend to create without needing to maintain a separate class for each type of Person.

1
2
3
4
5
6
7
8
9

        // Stratergy Demo

        Person slowRunner = new Person("Flash", new FastRunner());
        slowRunner.run();


        Person fastRunner = new Person("Slowboy", new SlowRunner());
        fastRunner.run();