Implement the Strategy Pattern with Interchangeable Algorithm Classes in Python
Uses abstract base classes to define a SortStrategy interface, then swaps between BubbleSort and QuickSort at runtime.
Python code
50 linesfrom abc import ABC, abstractmethod
from typing import List
class SortStrategy(ABC):
@abstractmethod
def sort(self, data: List[int]) -> List[int]:
pass
class BubbleSort(SortStrategy):
def sort(self, data: List[int]) -> List[int]:
result = data[:]
n = len(result)
for i in range(n):
for j in range(0, n - i - 1):
if result[j] > result[j + 1]:
result[j], result[j + 1] = result[j + 1], result[j]
return result
class QuickSort(SortStrategy):
def sort(self, data: List[int]) -> List[int]:
if len(data) <= 1:
return data[:]
pivot = data[0]
left = [x for x in data[1:] if x <= pivot]
right = [x for x in data[1:] if x > pivot]
return self.sort(left) + [pivot] + self.sort(right)
class SortContext:
def __init__(self, strategy: SortStrategy):
self._strategy = strategy
def set_strategy(self, strategy: SortStrategy) -> None:
self._strategy = strategy
def execute_sort(self, data: List[int]) -> List[int]:
return self._strategy.sort(data)
if __name__ == "__main__":
numbers = [5, 2, 9, 1, 7, 3]
context = SortContext(BubbleSort())
print("Bubble sort:", context.execute_sort(numbers))
context.set_strategy(QuickSort())
print("Quick sort: ", context.execute_sort(numbers))
Output
Bubble sort: [1, 2, 3, 5, 7, 9]
Quick sort: [1, 2, 3, 5, 7, 9]
How it works
The SortStrategy abstract base class defines a sort contract that any algorithm must follow. Each concrete strategy, BubbleSort and QuickSort, implements this method with a different algorithm while keeping the same interface, so they can be swapped freely. The SortContext holds a reference to a strategy and delegates the sorting call through execute_sort, making the client independent of the chosen algorithm. By using set_strategy, the context can change behaviour at runtime without modifying the code that uses it, which is the core benefit of the Strategy pattern.
Common mistakes
- Not copying the input list in BubbleSort, mutating the caller's data instead
- Forgetting the strategy must implement every abstract method or the class stays abstract
- Swapping strategies inside a method that expects a fixed algorithm
Variations
- Use a function-based strategy by passing a callable instead of an object with a sort method
- Store the strategy in a dictionary keyed by name and look it up dynamically
Real-world use cases
- Selecting a compression or encryption algorithm at runtime based on data size or security level.
- Letting a payment processor swap between card, PayPal, or bank transfer handlers without touching the main checkout flow.
- Switching validation rules for a REST endpoint depending on environment or user role.
Sponsored
More from OOP & classes
- Add property getter setter validation in Python easy
- Binary Tree Inorder Traversal in Python easy
- Borg pattern shared state in Python medium
- Bridge Pattern in Python: Separate Abstraction from Implementation medium
- Composable Predicates with the &, |, ~ Operators in Python medium
- Composition over Inheritance: How to Build a Wallet Account in Python easy
Keep learning
Related tutorials and quizzes for this topic.