Solving Parameter Bloat in the Strategy Pattern
Overview
The Strategy Pattern allows developers to swap algorithms at runtime without altering the client code. However, a common friction point arises when different strategies require unique parameters. If a ZipCompression strategy needs a compression_level while Zlib needs chunk_size, where do these settings live? Failing to handle this correctly leads to leaking implementation details into the high-level classes that use these strategies.
Prerequisites
To follow this guide, you should be comfortable with Python classes, abstract base classes, and Dependency Injection. Familiarity with Data Classes is also recommended.
Key Libraries & Tools
- ABC: Python's built-in module for defining Abstract Base Classes.
- Dataclasses: A decorator and functions for automatically adding generated special methods to user-defined classes.
Code Walkthrough
The Wrong Way: Keyword Arguments
One might try adding **kwargs to the strategy methods. This allows passing any parameter, but it destroys type safety and code clarity.
def should_buy(self, prices: list[float], **kwargs: float) -> bool:
window_size = kwargs.get("window_size", 3)
# Logic here...
The Messy Way: The Monster Parameter Class
Creating a single StrategyParameters data class to hold every possible option creates tight coupling. Every strategy then depends on a giant object containing parameters it doesn't even use.
The Best Way: Strategy Initializers
The most robust solution leverages the power of objects to combine data with behavior. By passing parameters into the strategy's __init__ method, you keep the execution methods clean.
@dataclass
class MinMaxStrategy(TradingStrategy):
min_price: float
max_price: float
def should_buy(self, prices: list[float]) -> bool:
return prices[-1] < self.min_price
Syntax Notes
Using the @dataclass decorator significantly reduces boilerplate code by automatically generating the __init__ method. This keeps your strategy definitions concise while maintaining explicit parameter requirements.
Practical Examples
In a trading bot, a Bitcoin strategy might need much wider price thresholds than a stablecoin strategy. By using initializers, the main setup function configures these specific values once. The bot itself remains oblivious to these numbers, simply calling should_buy() on whatever strategy it was given.
Tips & Gotchas
Avoid the trap of "parameter leakage." If your bot's run method has to know that a strategy needs a window_size, you have broken the abstraction. Always set specific configuration at the point of instantiation where the concrete class is already known.
- Bitcoin
- 17%· cryptocurrency
- Data Classes
- 17%· software development
- Dependency Injection
- 17%· software development
- Ethereum
- 17%· cryptocurrency
- Python
- 17%· programming languages
- Strategy Pattern
- 17%· software development

Solving A Common Issue With The Strategy Pattern // In Python
WatchArjanCodes // 14:43
On this channel, I post videos about programming and software design to help you take your coding skills to the next level. I'm an entrepreneur and a university lecturer in computer science, with more than 20 years of experience in software development and design. If you're a software developer and you want to improve your development skills, and learn more about programming in general, make sure to subscribe for helpful videos. I post a video here every Friday. If you have any suggestion for a topic you'd like me to cover, just leave a comment on any of my videos and I'll take it under consideration. Thanks for watching!