# Strategy Pattern
The **Strategy Pattern** defines a family of interchangeable algorithms behind a common interface and lets the client choose which one to use at runtime. Instead of branching on a type or mode inside one class (`if (mode == "fast") {...} else if (mode == "thorough") {...}`), each algorithm is encapsulated in its own object that implements a shared `Strategy` interface, and the client holds a reference to whichever strategy is active.
It's one of the original 23 Gang of Four patterns (Gamma, Helm, Johnson, Vlissides — *Design Patterns*, 1994). Strategy is a structural ally of [[Composition over Inheritance]]: it replaces inheritance hierarchies that vary by behavior with a small interface plus pluggable implementations.
## Structure
```
Context ──holds──> Strategy (interface)
△
│ implements
┌──────────────┼──────────────┐
│ │ │
ConcreteA ConcreteB ConcreteC
```
- **Strategy** — the abstraction defining the operation (`compress(bytes) -> bytes`).
- **ConcreteStrategy** — one implementation per algorithm (Gzip, Brotli, Zstd).
- **Context** — holds a reference to a Strategy and delegates to it.
The Context doesn't know *which* strategy it has; it only knows the interface.
## Why it matters
- **Open for extension, closed for modification**: new algorithms ship as new classes, not as new branches in an existing one. See [[Open Closed Principle (OCP)]].
- **Eliminates conditional dispatch**: long `if/else` or `switch` chains driven by a "type" field collapse into a single virtual call.
- **Enables runtime swapping**: the active strategy can change between calls, between requests, or between users.
- **Testability**: each strategy is a small unit you can test in isolation; the Context can be tested with a stub strategy.
## Strategy as an IoC mechanism
Strategy is a form of [[Inversion of Control (IoC)]]: the Context surrenders the *decision* of "which algorithm to run" to whatever code wired it up. The Context calls the strategy; the strategy was chosen by someone else (often via [[Dependency Injection (DI)]] from a [[Composition Root]]).
## When to reach for it
- More than two algorithms vary along the same axis.
- The set of algorithms is expected to grow.
- The selection logic doesn't belong inside the consumer.
- You're tempted to subclass just to override one method — Strategy is usually cleaner.
## When NOT to reach for it
- Only two variants and they're stable — a boolean flag and an `if` is simpler.
- The "algorithms" are really data (e.g., currency rates) — use a lookup table.
- The variants need radically different inputs — Strategy fits *interchangeable* algorithms; if signatures diverge, the abstraction is leaking.
## Idiomatic forms by language
- **OO languages**: classes implementing an interface.
- **Functional / TS / JS / Python**: pass a function (lambda, closure) — Strategy degenerates into "higher-order function."
- **First-class functions ARE Strategy**. Don't ceremonially wrap a one-method interface around what could be `(x) => ...`.
## Related Gang-of-Four cousins
- **[[Template Method]]** — same intent (vary an algorithm) but uses *inheritance* instead of composition. Template Method fixes the skeleton in a base class; Strategy makes the whole algorithm pluggable. Strategy is usually preferable.
- **State** — same structure as Strategy, different intent: State models lifecycle transitions; Strategy models algorithm choice.
- **Command** — Command encapsulates a *request* (parameters + invoker). Strategy encapsulates a *how*.
## References
- Gang of Four — *Design Patterns: Elements of Reusable Object-Oriented Software* (1994), Strategy chapter
- Refactoring Guru — https://refactoring.guru/design-patterns/strategy
## Related
- [[Template Method]]
- [[Observer Pattern]]
- [[Composition over Inheritance]]
- [[Open Closed Principle (OCP)]]
- [[Inversion of Control (IoC)]]
- [[Dependency Injection (DI)]]
- [[SOLID Principles]]