The Strategy pattern defines a set of interchangeable algorithms, each in its own class. It lets you switch between these algorithms at runtime without changing the core logic of your program.
When a function needs to perform similar tasks in different ways—like sorting data using different criteria—you might end up with a lot of if-else
or switch
statements. The Strategy pattern helps by isolating each variation into its own class, making the code cleaner and easier to extend.
Use this pattern when:
Avoid this pattern if:
The Strategy pattern includes three parts:
Imagine a restaurant with different menus. You pick the menu based on your mood—vegetarian, vegan, or seafood. The kitchen (context) prepares your meal based on your choice, without changing how it operates behind the scenes.
Here’s a basic Python example:
from abc import ABC, abstractmethod
# Strategy interface
class SortStrategy(ABC):
@abstractmethod
def sort(self, data: list[int]) -> list[int]:
pass
# Concrete strategy
class AscendingSortStrategy(SortStrategy):
def sort(self, data: list[int]) -> list[int]:
return sorted(data)
# Context
class Context:
def __init__(self, strategy: SortStrategy):
self._strategy = strategy
def set_strategy(self, strategy: SortStrategy):
self._strategy = strategy
def sort(self, data: list[int]) -> list[int]:
return self._strategy.sort(data)
data = [5, 2, 9, 1]
context = Context(AscendingSortStrategy())
print(context.sort(data)) # Output: [1, 2, 5, 9]
You can switch the strategy by calling set_strategy()
with a different sorting class.
See the complete Python implementation here: Strategy Pattern on GitHub