Strategy Design Pattern

The Strategy Design Pattern allows us to change the behaviour of a class at runtime. In Strategy pattern we create various algorithm classes implementing a common Strategy interface. The Context object has a reference to a Strategy object and we can change the behaviour of the Context object by changing it's strategy object reference.

Strategy pattern is used to encapsulate the variable behaviour of Context object as a set of strategy classes, So that we can vary the behaviour of Context object on run time.

Strategy Pattern evolves three actors

  • Strategy : We define a common interface which every algorithm class must implement. Context interacts with various strategy implementation using this interface only. Context is not aware of that with which Strategy implementation he is interacting with.
  • ConcreteStrategy Classes : Concrete implementation of Strategy interface. Each class implementing Strategy interface implements an algorithm.
  • Context : It contains a reference to Strategy object. A context implements all common behaviours which doesn't vary and depends on Strategy object for performing any variable behaviour. When context object receives requests from the client to perform any variable behaviour it delegates them to the Strategy object.
For Example
, We are designing a new Abstract Data Type ArrayADT which is a wrapper over Array. We don't want to hard-code any specific sorting algorithm for sorting array elements instead we will let client to specify which sorting algorithm he wants to use. We will define an interface 'SortingAlgo' containg sort() mothod. ArrayADT will contain a reference to SortingAlgo object and we will provide a public method in ArrayADT to set SortingAlgo object. To sort the array, ArrayADT will delegate request to SortingAlgo object. Now, We can write multiple concrete classes implementing SortingAlgo interface like 'BubbleSort', 'QuickSort', 'MergeSort' etc.

Advantages of Strategy Pattern

  • It allows us to change the behaviour of the application at runtime.
  • We can add new behaviour or modify existing behaviour of the application without modifying context class.
  • It uses composition instead of inheritance. Instead of providing different behaviours by creating subclasses and overriding methods of superclasses, it contains a reference to a strategy interface which can point to any Concrete strategy object as per our requirement.

When we should use Strategy Pattern

  • When We want to change the behaviour of a class at runtime.
  • When we want to decouple the Context class form its variable behaviour. We can add or modify a ConcreteStrategy without modifying Context class.

Implementation of Strategy Design Pattern

Here, we will use strategy pattern to design a Soldier class for a video game, in which a player can change the gun of the solder any time. First of all, we will define a Strategy interface called 'Gun'. Different types of guns must implement Gun interface.

Gun.java
public interface Gun {
    public void fire();
}

We will define various weapon available for soldier. Each weapon is implemented as ConcreteStrategy class implementing Gun interface.

Snipper.java
public class Snipper implements Gun {
    public void fire(){
 System.out.println("This is Snipper Gun," + 
            "Firing one bullet at a time");
    } 
}

MachineGun.java
public class MachineGun implements Gun {
    public void fire(){
 System.out.println("This is Machine Gun," + 
            "Firing 100 bullets at a time");
    }
}

Snipper.java
public class GrenadeLauncher implements Gun {
    public void fire(){
 System.out.println("This is Grenade Launcher," +
            "Throwing one grenade");
    } 
}

Now, we will define Soldier(Context) class having a reference to Gun object and a public method 'changeGun' for changing its Gun reference(Strategy object)

Soldier.java
public class Soldier {
    private Gun gun;
 
    public Soldier(Gun gun){
 this.gun = gun;
    }
 
    public void changeGun(Gun gun){
 this.gun = gun;
    }
 
    public void fireAtEnemy(){
 gun.fire();
    }
}

StrategyPatternExample class demonstrate the changing of Guns(Strategy) of soldier(Context) at runtime.

StrategyPatternExample.java
/**
 * In this class we will dynamically change the Gun of a soldier as Soldier 
 * deals with Gun interface not concrete implementation of Gun.
 */
public class StrategyPatternExample {
    public static void main(String args[]) {
        Gun snipper = new Snipper();
 Gun machineGun = new MachineGun();
 Gun grenadelauncher = new GrenadeLauncher();
  
 // Create a soldier object with Snipper gun 
 Soldier commando = new Soldier(snipper);
 commando.fireAtEnemy();
 // Change the gun of commando to Machine Gun
 commando.changeGun(machineGun);
 commando.fireAtEnemy();
 // Change the gum of commando to Grenade Launcher
 commando.changeGun(grenadelauncher);
 commando.fireAtEnemy();
    }
}

Output

This is Snipper Gun, Firing one bullet at a time
This is Machine Gun, Firing 100 bullets at a time
This is Grenade Launcher, Throwing one grenade

Related Topics
State Design Pattern
Command Design Pattern
Composite Design Pattern
Singleton Design Pattern
Builder Design Pattern
Mediator Design Pattern
Factory Design Pattern
Facade Design Pattern
Interpreter Design Pattern
Bridge Design Pattern
List of Design Patterns