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.

Medium Python 3.9+ Aug 9, 2026 OOP & classes 12 views 0 copies

Python code

50 lines
Python 3.9+
from 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

stdout
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

  1. Use a function-based strategy by passing a callable instead of an object with a sort method
  2. 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

Run this sample

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

Open editor

More from OOP & classes

Related tutorials and quizzes for this topic.