Behavioral Design Patterns provide solution for the better interaction between objects and how to provide lose coupling and flexibility to extend easily. Following design patterns come under this category.
Strategy pattern allows you to switch the algorithm or strategy based upon the situation.
The Strategy pattern is useful when there is a set of related algorithms and a client object needs to be able to dynamically pick and choose an algorithm from this set that suits its current need. The Strategy pattern suggests keeping the implementation of each of the algorithms in a separate class. Each such algorithm encapsulated in a separate class is referred to as a strategy. An object that uses a strategy object is often referred to as a context object.
In other words, Strategy pattern is used when we have multiple algorithms for a specific task and client decides the actual implementation to be used at runtime. Strategy pattern is also known as Policy pattern. We define multiple algorithms and let client application pass the algorithm to be used as a parameter. One of the best example of this pattern is Collections.sort()
method that takes Comparator parameter. Based on the different implementations of Comparator
interfaces, the objects are getting sorted in different ways.
The Strategy pattern is one way that composition can be used as an alternative to subclassing. Rather than providing different behaviors via subclasses overriding methods in super classes, the strategy pattern allows different behaviors to be placed in concrete strategy classes which share the common strategy interface. A context object contains a reference to a strategy. By changing the context's strategy, different behaviors can be obtained.
There are three participants in the Strategy pattern
Let's take a look at how some client might put the Strategy pattern into action.
When to use the Strategy design pattern
Java
Here is an example of the strategy pattern. First, we'll define a Strategy
interface. It declares a checkTemperature()
method.
File Strategy.java.
public interface Strategy { boolean checkTemperature(int temperatureInF); }
The HikeStrategy
class is a concrete strategy class that implements the Strategy
interface. The checkTemperature
method is implemented so that if the temperature is between 50 and 90, it returns true
. Otherwise it returns false
.
File HikeStrategy.java.
public class HikeStrategy implements Strategy { @Override public boolean checkTemperature(int temperatureInF) { if ((temperatureInF >= 50) && (temperatureInF <= 90)) { return true; } else { return false; } } }
The SkiStrategy
implements the Strategy
interface. If the temperature is 32 or less, the checkTemperature method returns true. Otherwise it returns false.
File SkiStrategy.java.
public class SkiStrategy implements Strategy { @Override public boolean checkTemperature(int temperatureInF) { if (temperatureInF <= 32) { return true; } else { return false; } } }
The Context
class contains a temperature
and a reference to a Strategy
. The Strategy
can be changed, resulting in different behavior that operates on the same data in the Context
. The result of this can be obtained from the Context
via the getResult()
method.
File Context.java.
public class Context { int temperatureInF; Strategy strategy; public Context(int temperatureInF, Strategy strategy) { this.temperatureInF = temperatureInF; this.strategy = strategy; } public void setStrategy(Strategy strategy) { this.strategy = strategy; } public int getTemperatureInF() { return temperatureInF; } public boolean getResult() { return strategy.checkTemperature(temperatureInF); } }
The Demo
class creates a Context
object with a temperature of 60 and with a SkiStrategy
. It displays the temperature from the context and whether that temperature is OK for skiing. After that, it sets the Strategy
in the Context
to HikeStrategy
. It then displays the temperature from the context and whether that temperature is OK for hiking.
File Demo.java.
public class Demo { public static void main(String[] args) { int temperatureInF = 60; Strategy skiStrategy = new SkiStrategy(); Context context = new Context(temperatureInF, skiStrategy); System.out.println("Is the temperature (" + context.getTemperatureInF() + "F) good for skiing? " + context.getResult()); Strategy hikeStrategy = new HikeStrategy(); context.setStrategy(hikeStrategy); System.out.println("Is the temperature (" + context.getTemperatureInF() + "F) good for hiking? " + context.getResult()); } }
Python 3
import abc class Strategy(metaclass=abc.ABCMeta): @abc.abstractmethod def check_temperature(self, temperature): pass class HikeStrategy(Strategy): def check_temperature(self, temperature): if temperature >= 50 and temperature <= 90: return True else: return False class SkiStrategy(Strategy): def check_temperature(self, temperature): if temperature <= 32: return True else: return False class Context: def __init__(self, temperature, strategy): self.temperature = temperature self.strategy = strategy def set_strategy(self, strategy): self.strategy = strategy def get_temperature(self): return self.temperature def get_result(self): return self.strategy.check_temperature(temperature) if __name__ == '__main__': temperature = 60 strategy_ski = SkiStrategy() context = Context(temperature, strategy_ski) print("Is the temperature ({} F) good for skiing? {}".format(context.get_temperature(), context.get_result())) strategy_hike = HikeStrategy() context.set_strategy(strategy_hike) print("Is the temperature ({} F) good for hiking? {}".format(context.get_temperature(), context.get_result()))