All topics
Patternsintermediate

Strategy Pattern

Encapsulating interchangeable algorithms or behaviors behind a common interface so they can be swapped at runtime without changing the code that uses them.

Interchangeable behaviours behind a common shape, selected at runtime.

The Strategy pattern is like a GPS navigation app offering several route-calculation modes — fastest, shortest, avoid tolls — where the app's core turn-by-turn guidance logic doesn't care which specific mode you picked, it just plugs whichever route-calculation strategy you selected into the same guidance system, and adding a brand-new 'scenic route' mode later doesn't require touching the guidance engine itself at all.

Key Concepts

1
    const strategies = {
      card:   (amount) => chargeCard(amount),
      upi:    (amount) => chargeUpi(amount),
      wallet: (amount) => chargeWallet(amount)
    };
2
    function pay(method, amount) {
      const strategy = strategies[method];
      if (!strategy) throw new Error(`unsupported method ${method}`);
      return strategy(amount);
    }
unsupported method ${method}
3
What it replaces.
    function pay(method, amount) {
      if (method === 'card') { ... }
      else if (method === 'upi') { ... }
      else if (method === 'wallet') { ... }
    }
4
Adding a method means editing this function. With strategies, it means adding a key — and the existing code is untouched, which is the whole argument.
5
In JavaScript, a strategy is usually just a function. Other languages need an interface and a class per strategy; here a plain object of functions does it.
6
Where it appears naturally.
    arr.sort(comparator)              the comparator is a strategy
    validators[field](value)
    formatters[locale](date)
    retryPolicies[type](attempt)
7
Array.prototype.sort is the clearest everyday example: the algorithm is fixed, the comparison is supplied.
Array.prototype.sort
8
When it earns its place. Several interchangeable algorithms for one job, chosen at runtime, and likely to grow.
9
When it does not. Two cases that will never become three. A switch is clearer than indirection for that, and adding a strategy registry is work for no benefit.
switch
10
The practical detail: a default.
    const strategy = strategies[method] ?? strategies.default;
11
Without one, an unknown key gives undefined and the failure is a confusing "not a function" rather than a message naming the problem.
undefined
12
And extensibility. Because the registry is an object, strategies can be added from elsewhere:
13
    registerPaymentMethod('netbanking', chargeNetbanking);
14
That is what makes it a plugin point rather than a tidier switch — the set of behaviours is open, and code that does not know about a new one keeps working.
switch
15
What the interviewer is probing.1. "How does JavaScript simplify this pattern?" Probing: first-class functions. Stalls: "It does not." Moves up: a strategy is just a function, so the interface and the classes disappear and a map of functions replaces the switch.
16
2. "How does it satisfy open/closed?" Probing: the principle. Stalls: "It is tidier." *Moves up:* adding a strategy is adding a map entry; no existing code is edited.
17
3. "When is an object with methods better than a bare function?" Probing: the limit. Stalls: "Never." Moves up: when the strategy needs state or several related operations.
18
4. "Where do you see it in the standard library?" Probing: recognition. Stalls: "Nowhere." Moves up: the comparator passed to sort, and the predicate passed to filter.