Last updated: Apr 29, 2026

Strategy

Strategy replaces conditional logic with polymorphism. Use it when there are different ways of doing the same thing and you want to swap them at runtime — for example, validation rules, payment methods, or other algorithms.

How It Works

Three roles collaborate:

  1. Strategy — an interface that every concrete algorithm implements.
  2. ConcreteStrategy — a specific implementation of that interface.
  3. Context — holds a reference to a Strategy and delegates calls to it. The context (and its callers) never depend on a concrete implementation.

The client picks a concrete strategy and injects it into the context. Switching behavior means swapping the strategy object — no conditionals, no subclassing.

Example in TypeScript

interface PaymentStrategy {
  pay(amount: number): string;
}

class CreditCardPayment implements PaymentStrategy {
  constructor(private card: string) {}

  pay(amount: number) {
    return `Charged $${amount} to credit card ${this.card}`;
  }
}

class PayPalPayment implements PaymentStrategy {
  constructor(private email: string) {}

  pay(amount: number) {
    return `Sent $${amount} via PayPal to ${this.email}`;
  }
}

class CryptoPayment implements PaymentStrategy {
  constructor(private wallet: string) {}

  pay(amount: number) {
    return `Transferred $${amount} in crypto to ${this.wallet}`;
  }
}

class Checkout {
  constructor(private strategy: PaymentStrategy) {}

  setStrategy(strategy: PaymentStrategy) {
    this.strategy = strategy;
  }

  process(amount: number) {
    return this.strategy.pay(amount);
  }
}

const checkout = new Checkout(new CreditCardPayment("4242-4242-4242-4242"));
console.log(checkout.process(99));
// Charged $99 to credit card 4242-4242-4242-4242

checkout.setStrategy(new PayPalPayment("user@example.com"));
console.log(checkout.process(49));
// Sent $49 via PayPal to user@example.com

Trade-Offs

AdvantageDisadvantage
Eliminates conditional logic — each algorithm lives in its own classIncreases the number of classes in the codebase
Strategies are independently testable and reusableClients must be aware of the available strategies to choose the right one
New algorithms can be added without modifying the context (Open/Closed)Overhead is unnecessary when only one or two algorithms exist and are unlikely to change