Published October 6, 2021
by Doug Klugh

Promoting Flexibility

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.

Pattern Benefits
Separation of Concernslaunch

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.

Conditional Statementslaunch

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. 

Polymorphic Dispatchlaunch

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.

Implementation Variants

Use strategies to provide different implementations of the same behavior.  For example, this can be used to dynamically trade space optimization for time optimization.

Decorator vs Strategy

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.