Strategy | Cheat Sheet

Behavioral Pattern — Design Patterns Series

Itchimonji
CP Massive Programming

--

Strategy is often used when wanting to switch between different algorithms or behaviour at runtime. Decoupling the logic makes this change very simple and elegant, and also allows easy expansion with new algorithms.

At the end there is an emergence of a family of related algorithms. Strategy is one of the best showcase patterns to understand and learn Dependency Inversion. The usage of Object Composition increases the number of objects in this case, but it’s an alternative to creating subclasses for all the algorithms.

Real-life examples

  • Selection of a sorting algorithm (MergeSort, QuickSort, HeapSort, …) at runtime
  • Selection of a browser storage (local storage, session storage, … ) at runtime
  • Building a hamburger
  • Using different kinds of encryption and decryption
  • Using different kinds of data compression
  • Using different golf clubs for different terrains
  • Travelling options from A to B

Meaning

  • Definition of a family of individually encapsulated and exchangeable algorithms
  • Allows variable and client independent use of an algorithm

Applicability (suitable if …)

  • A way must be provided to equip a class with one of many different behaviors
  • Different variants of an algorithm are necessary (e.g. different trade-offs between memory requirements and computation time)
  • The implementation of different variants of a class hierarchy of algorithms is necessary
  • An algorithm uses data of which the client has/should have no knowledge
  • Conditional statements are supposed to be wrapped in a separate class

Assets and Drawbacks

  • Emergence of a family of related algorithms (or behaviors)
  • An alternative to creating subclasses (composition makes the algorithm easily modifiable, replaceable, and extensible)
  • Eliminates the need for conditional statements due to polymorphism (e.g. when refactoring switch statements)
  • Different choices of implementations of the same behavior (tradeoff between memory requirements and computation time)
  • The client sometimes needs to know how Strategies differ from each other (conditional disclosure of implementations)
  • Additional effort in communication between Strategy and Context
  • Increased number of objects

Example

For this example I choose a simple Strategy to switch between different sort algorithms at run time. In order to be able to use Dependency Inversion, you first need an interface:

Using the interface, you can now implement different sort algorithms:

In a context class you can encapsulate the interface and its logic now:

With this implementation, the client can switch between different sort algorithms very easily:

Conclusion

Design Patterns are an important resource and base knowledge for every developer — they are very helpful for solving programmatic problems, help with consistent communication with other developers about system design, and serve as a significant introduction into object composition (besides inheritance) and dependency inversion.

Behavioral Patterns deal with algorithms and assignment of responsibilities to objects. Furthermore, they describe mutual communication patterns and grasp complex program sequences. They are therefore very well suited for use in areas where complicated code needs to be made readable and maintainable. Extensions are in consequence very good and quickly implementable.

--

--

Itchimonji
CP Massive Programming

Freelancer | Site Reliability Engineer (DevOps) / Kubernetes (CKAD) | Full Stack Software Engineer | https://patrick-eichler.com/links