The strategy pattern allows us to change the behavior of a type by switching algorithms.
The pattern works by defining a common interface for a family of algorithms. Each algorithm gets encapsulated in its own strategy type. The client only depends on the interface, so it can vary the algorithm by simply switching the concrete strategy object. There is a context, which delegates the client request to its strategy. The strategy is a protocol; it defines a common interface for all concrete algorithms. The concrete strategy types implement a specific algorithm. Clients instantiate the context with a concretestrategy object. The algorithm can then be updated by applying a different strategy instance to the context.
- Identify a behavior that the client would prefer to access.
- Specify the signature for that algorithm in an interface.
- Bury the alternative implementation details in derived classes.
- Clients of the algorithm couple themselves to the interface.
The strategy pattern is about decoupling the algorithm implementation details from the type that uses it. This allows changing the object’s behavior at runtime by switching algorithms.
Modes of transport to travel to one place to another would be a trivial example but suits aptly IMHO. I can choose my own car or a public transport – bus or cab or I can choose flight. I can choose any of these whenever I want to commute.
Logger system with options like logging to Console or logging to file or logging in memory. User can choose the strategy at the time of usage.
So the strategy should be used if you need to implement algorithms that need to be used interchangeably. The algorithm is decoupled from the type that uses it. The context only sees the protocol, which allows clients to easily switch between the various implementations. Another benefit of the strategy pattern is that it lets us add new algorithms without modifying the class that uses them.
The strategy pattern is so straightforward that there are no pitfalls I could mention.