Strategy Pattern
The strategy pattern is a particular software design pattern, whereby algorithms can be selected at
runtime. Formally speaking, 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.
For instance, a class that performs validation on incoming data may use a strategy pattern to select a validation algorithm based on the type of data, the source of the data, user choice, and/or other discriminating factors. These factors are not known for each case until run-time, and may require radically different validation to be performed. The validation strategies, encapsulated separately from the validating object, may be used by other validating objects in different areas of the system (or even different systems) without code duplication.
The essential requirement in the programming language is the ability to store a reference to some code in a data structure and retrieve it. This can be achieved by mechanisms such as the native function pointer, the first-class function, classes or class instances in object-oriented programming languages, or accessing the language implementation’s internal storage of code via reflection.
Structure diagram :
Example:
The Context class uses this to call the concrete strategy.
public interface IStrategy { int execute(int a, int b); }
Implements the algorithm using the strategy interface
public class ConcreteStrategyAdd implements IStrategy { public int execute(int a, int b) { System.out.println("Called ConcreteStrategyAdd's execute()"); return a + b; } }
public class ConcreteStrategySubtract implements IStrategy { public int execute(int a, int b) { System.out.println("Called ConcreteStrategySubtract's execute()"); return a - b; // Do a subtraction with a and b } }
public class ConcreteStrategyMultiply implements IStrategy { public int execute(int a, int b) { System.out.println("Called ConcreteStrategyMultiply's execute()"); return a * b; // Do a multiplication with a and b } }
Configured with a ConcreteStrategy object and maintains a reference to a Strategy object
public class Context { private IStrategy strategy; // Constructor public Context(IStrategy strategy) { this.strategy = strategy; } public int executeStrategy(int a, int b) { return strategy.execute(a, b); } }
Main test class:
public class StrategyExample { public static void main(String[] args) { Context context; // Three contexts following different strategies context = new Context(new ConcreteStrategyAdd()); int resultA = context.executeStrategy(3, 4); System.out.println("Result: "+resultA); context = new Context(new ConcreteStrategySubtract()); int resultB = context.executeStrategy(3, 4); System.out.println("Result: "+resultB); context = new Context(new ConcreteStrategyMultiply()); int resultC = context.executeStrategy(3, 4); System.out.println("Result: "+resultC); } }