Behavioral pattern
Strategy
A context needs to run one of several interchangeable algorithms — Strategy hides each one behind a common interface so the context never has to know which one it's running.
✗ The problem
A growing if/else picks the algorithm
Every new payment method means editing this one function again.
function checkout(amount, type) {
if (type === 'card') return amount * 1.029 + 0.30;
if (type === 'paypal') return amount * 1.034;
if (type === 'crypto') return amount + 1.00;
// new method? reopen and edit this again…
}
All three algorithms are tangled inside one function — you can't test
card math without dragging paypal and crypto along, and
adding a fourth method means reopening code that already works.
✓ The pattern
↓
↑
Extract each algorithm behind one interface
The context holds a strategy object and just delegates to it.
It has no idea which concrete algorithm is running.
class PaymentStrategy {
pay(amount) { /* override me */ }
}
class CardStrategy extends PaymentStrategy {
pay(amount) {
return amount * 1.029 + 0.30;
}
}
class Checkout {
constructor(strategy) {
this.strategy = strategy;
}
checkout(amount) {
return this.strategy.pay(amount);
}
}
Checkout
holds a strategy
PaymentStrategy
interface: pay(amount)
CardStrategy
PaypalStrategy
CryptoStrategy
Strategy is how you realize Open/Closed for
interchangeable algorithms — a new payment method is a new class, not an edit to
Checkout.
✓ See it live
Swap the algorithm at runtime
Pick a strategy, then run checkout on a fixed $100 charge. The
Checkout context stays the same — only which strategy it holds changes.
💳 Card
2.9% + $0.30
🅿️ PayPal
3.4%
₿ Crypto
flat $1.00
Pick a strategy above, then pay
Tip: click another strategy and pay again — same amount, different fee.
✓ Takeaway
Interchangeable algorithms, no rewrites
- Swap algorithms at runtime by handing the context a different strategy object.
- Each strategy tested in isolation — no if/else chain to drag along.
- Add a strategy = add a class.
Checkoutnever changes (Open/Closed). - Careful: overkill for one stable algorithm that never varies — that's just YAGNI.
🎯 Principle applied: Strategy is how you get Open/Closed for algorithms — add a new strategy class without touching the context — and Dependency Inversion: the context depends on the
PaymentStrategy interface, never a concrete algorithm. Each strategy is independently testable (SRP).Back to all topics →