Strategy Pattern
The Strategy pattern defines a family of interchangeable algorithms or behaviors, encapsulates each one, and allows them to be swapped at runtime without modifying the calling code.
This pattern is useful when multiple approaches exist to perform a task, and you want to select the appropriate one dynamically, promoting cleaner logic and improved maintainability.
This pattern should be implemented manually: it does not require built-in helpers from pattern_kit.
Use Cases
Switching between different sorting or filtering strategies
Applying different pricing, tax, or discount rules
Customizing logging, serialization, or validation logic
Pluggable behavior in UI elements or background tasks
AI/game agents choosing a decision-making strategy
Example
from abc import ABC, abstractmethod
class DiscountStrategy(ABC):
@abstractmethod
def apply(self, price: float) -> float:
pass
class NoDiscount(DiscountStrategy):
def apply(self, price):
return price
class TenPercentOff(DiscountStrategy):
def apply(self, price):
return price * 0.9
# Usage
def calculate_total(price: float, strategy: DiscountStrategy) -> float:
return strategy.apply(price)
print(calculate_total(100, NoDiscount())) # 100.0
print(calculate_total(100, TenPercentOff())) # 90.0
Benefits
Eliminates long if/else blocks
Makes algorithms testable in isolation
Allows behavior to change at runtime
Encourages composition over inheritance