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 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.
, 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 Design Pattern
- Algorithm Encapsulation : The pattern encapsulates algorithms in separate strategy classes, promoting a clean separation of concerns. Each strategy class focuses on a specific algorithm, making the code more modular.
- Open/Closed Principle : The pattern supports the Open/Closed Principle, allowing new strategies to be added without modifying existing code. This contributes to the maintainability and stability of the system.
- Easy Algorithm Swapping : The context can easily switch between different algorithms at runtime by changing the current strategy. This flexibility allows for dynamic adaptation to changing requirements.
- Promotes Code Reusability : Concrete strategy classes can be reused across different contexts if they implement the same strategy interface. This reusability is beneficial when similar algorithms are needed in multiple parts of a system.
- Adaptability to Changing Requirements : The Strategy Design Pattern is adaptable to changing requirements. New strategies can be introduced, and existing strategies can be modified or extended without disrupting the overall structure of the system.
- Reduced Code Duplication : The pattern helps reduce code duplication by providing a structured way to organize and reuse algorithmic code. This is particularly valuable when multiple components in a system require similar algorithms.
- Enhanced Maintainability : Maintenance is enhanced as changes to one algorithm do not affect other parts of the system. Modifications or additions to strategies are localized, reducing the risk of unintended side effects.
- Clear Separation of Concerns : The separation of concerns between the context and strategies results in a clear and modular design. The context focuses on managing algorithms, while strategies focus on implementing specific algorithms.
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.

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.javapublic 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"); } }
GrenadeLauncher.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.javapublic 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
Best Practices of Strategy Design Pattern
- Ensure that the strategy interface clearly defines the methods that represent the algorithm. A well-defined interface facilitates the implementation of concrete strategy classes.
- Each concrete strategy class should encapsulate a specific algorithm variation. Avoid mixing multiple algorithms within a single strategy class to maintain clarity and modularity.
- Consider using an abstract class for the strategy instead of an interface if there are common behaviors shared among multiple strategy classes. This abstract class can provide default implementations for shared behavior.
- Consider providing a default strategy in the context class to handle cases where a specific strategy is not set explicitly. This default strategy helps prevent null references and ensures consistent behavior.
- Minimize the frequency of switching strategies at runtime. Frequent switching may introduce unnecessary complexity and reduce the effectiveness of the pattern.
- Consider using dependency injection to provide strategies to the context. This allows for more flexibility in substituting different strategy implementations, making the system easier to extend.
- Provide clear documentation for each strategy class, specifying the behavior expected in each strategy. This documentation helps developers understand how to implement new strategy classes.
- Decide whether state information should be managed in the context or within the individual strategy classes. Considerations may include the need for shared state or whether state should be specific to each strategy.
- Decide whether the initial strategy should be set during the context's construction or if it should be set explicitly by client code. Consider the initialization strategy that best fits the requirements of your application.
- Unit test each concrete strategy class in isolation to ensure that it behaves correctly according to its defined contract. This promotes the reliability of individual strategy implementations.
State Design Pattern |
Command Design Pattern |
Composite Design Pattern |
Singleton Design Pattern |
Builder Design Pattern |
List of Design Patterns |