How to Implement the Strategy Pattern in Python

This Python code demonstrates the Strategy design pattern using interchangeable sorting algorithms (bubble sort and quick sort) that can be swapped at runtime.

Medium Python 3.9+ Aug 9, 2026 System design patterns 13 views 0 copies

Python code

39 lines
Python 3.9+
class SortingStrategy:
    def sort(self, data):
        raise NotImplementedError

class BubbleSort(SortingStrategy):
    def sort(self, data):
        result = data.copy()
        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(SortingStrategy):
    def sort(self, data):
        if len(data) <= 1:
            return data.copy()
        pivot = data[0]
        less = [x for x in data[1:] if x <= pivot]
        greater = [x for x in data[1:] if x > pivot]
        return self.sort(less) + [pivot] + self.sort(greater)

class Sorter:
    def __init__(self, strategy):
        self._strategy = strategy

    def set_strategy(self, strategy):
        self._strategy = strategy

    def execute(self, data):
        return self._strategy.sort(data)

if __name__ == "__main__":
    numbers = [3, 1, 4, 1, 5, 9, 2, 6]
    sorter = Sorter(BubbleSort())
    print("Bubble:", sorter.execute(numbers))
    sorter.set_strategy(QuickSort())
    print("Quick:", sorter.execute(numbers))

Output

stdout
Bubble: [1, 1, 2, 3, 4, 5, 6, 9]
Quick: [1, 1, 2, 3, 4, 5, 6, 9]

How it works

The Strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable at runtime. Here, SortingStrategy is an abstract base class with a sort method that subclasses must implement. BubbleSort and QuickSort provide concrete algorithms by overriding sort. The Sorter class holds a reference to a strategy and delegates the sorting task to it, allowing clients to switch algorithms without modifying the Sorter code. This separation of concerns promotes code reuse and makes the system flexible and easier to maintain.

Common mistakes

  • Not creating a common interface for strategies, leading to code that checks class types explicitly.
  • Reusing a list reference instead of copying, causing the original data to be modified unexpectedly.
  • Forgetting to handle base cases in recursive algorithms like quicksort, leading to infinite recursion or errors.

Variations

  1. Use `functools.singledispatch` to implement similar behavior with function overloading.
  2. Make strategy selection based on data size or constraints dynamically in the sorter.

Real-world use cases

  • Choosing between different compression algorithms (e.g., gzip vs. bzip2) at runtime in backup and file archival tools.
  • Selecting a payment gateway strategy (e.g., credit card, PayPal, crypto) in e-commerce applications based on user preference.
  • Implementing different authentication methods (e.g., OAuth, JWT, API key) that are interchangeable in an API security layer.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from System design patterns

Related tutorials and quizzes for this topic.