Design patterns series — part 1
There are 23 classical design patterns described in the book
Design Patterns: Elements of Reusable Object-Oriented Software. These patterns provide a solution to a particular problem, one which is repeated in the software development.
In this piece I will look at the strategy pattern — how it works, how and when it should be apply. This pattern is known as policy in other contexts.
Strategy Pattern: Basic Idea
The strategy pattern is a behavioral design pattern that enables selecting an algorithm at runtime
Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
— Design Patterns: Elements of Reusable Object-Oriented Software
The main feature of this pattern is that the client has a set of algorithms in which a specific algorithm will be selected for use during runtime. These algorithms are interchangeable between them.
The following code show the classical problem, one in which you need to select a concrete algorithm in your app. In this code, you use the
switch control structure of any programming language.
However, it can be more flexible using the Strategy Pattern which takes the following structure:
The UML’s diagram of this pattern:
Each strategy is represented with a concrete object. So, the client/context contains a
Strategy object (
concreteStrategyB,…) which implements the interface
Strategy. The key interchange consists in implementing a method in context, which changes the instance of strategy. For example:
When to Use the Strategy Pattern
- When you need to use several algorithms with different variations. You need create a concrete class to implement your algorithm (which can consist of
- When there are conditional statements around several related algorithms.
- When most of your classes have related behaviours.
Advantages of the Strategy Pattern
The Strategy Pattern has several advantages:
- It’s easy to switch between different algorithms (strategies) in runtime because you’re using polymorphism in the interfaces.
- Clean code because you avoid conditional-infested code (not complex).
- More clean code because you separate the concerns into classes (a class to each strategy).
StrategyManager, which is used as the interface:
This class contains a private attribute called
_strategy, which represents the strategy used. The method
The implementation of each concrete strategy is the following:
Note that the concrete method
doAction is implemented in each concrete strategy.
Finally, the context/client must contain the
StrategyManager (or strategy interface is the language is OO) to use the concrete strategy:
In the following implementation, our
StrategyManager gets more complex, containing a list of algorithms. In this case, you can change the attribute
_strategy instead of an array called
Finally, you add new strategies in the list of strategies using the method
Strategy class has two attributes: 1. Strategy’s name and 2. Algorithm (called
handler). The method
doAction is used to invoke the concrete algorithm.
Finally, the client/context code where we use the concrete strategy:
The first part is to create concrete strategies (which can be constructed using the
Singleton pattern and the
Factory pattern) and added to the
strategyManager (which could be our interface). The next part of the client is selecting the strategy to use — this strategy can be selected using a GUI or CLI from our app.
Finally, note that if an unsupported strategy is selected the system will return an error. This can be used when you want to provide a premium algorithm to your system.
If you liked this article and would like to read similar articles, don’t forget to clap.
Most importantly, don’t just implement the pattern as I’ve shown you here. You need to know what the problem is that the pattern resolves and why you should use it. The implementation will vary depending on the programming language.