# 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]]