Published October 6, 2021
by Doug Klugh
Build flexible software systems by encapsulating functionality within interchangeable classes. This requires related classes that differ only in their behavior. This pattern provides an alternative to conditional statements for selecting desired behavior and eliminates the need to recompile and redeploy a module (or an entire application) any time a condition is added or changed. Use this pattern to leverage polymorphism and promote compliance with the Open/Closed Principle and the Dependency Inversion Principle.
Use strategies to decouple your software system by separating high-level policy from low-level implementation. The high-level policies delegate requests through an abstract (strategy) class to derivatives that implement low-level functionality.
Use strategies as an alternative to conditional statements for selecting desired behavior. For example, you can replace the argument of a switch statement with a strategy class containing a method that corresponds to the operation of the switch. Then simply create concrete strategies and implement that method for each of the cases.
Encapsulate different algorithms in separate strategy classes to dynamically select the appropriate algorithm independently of its context. While you can use inheritance to create subclasses of a context, this will hard-wire static behavior into the context.
Use strategies to provide different implementations of the same behavior. For example, this can be used to dynamically trade space optimization for time optimization.
The Decorator Pattern and the Strategy Pattern both provide dynamic alternatives to subclassing. A good way to distinguish these patterns is to remember that a decorator effectively changes the skin of an object, while a strategy changes its guts. Strategies are used to configure classes that differ only in their behavior. One example would be to implement different algorithms to address different performance requirements.