The Strategy pattern ****uses Dependency Injection (DI) to provide an object runtime interchangeable behaviors.

Components

SOLID Principle

✅ Single Responsibility Principle (SRP)

✅  Open/Closed Principle (OCP)

✅  Liskov Substitution Principle (LSP) / Interface Segregation Principle (ISP)

✅  Dependency Inversion Principle (DIP)

Implementation

Inheritance + Composition (Less Common)

If there is no shared reused logics, it could introduce coupling. Coupling

Interface Polymorphism + Composition

Composition allows the algorithm (strategy) to be replaced dynamically without changing the client or context.

// Abstract Strategy
interface PaymentStrategy {
  pay(amount: number): void;
}

// Concrete Strategies
class CreditCardPayment implements PaymentStrategy {
  pay(amount: number): void {
    console.log(`Paid ${amount} using Credit Card.`);
  }
}
class PayPalPayment implements PaymentStrategy {
  pay(amount: number): void {
    console.log(`Paid ${amount} using PayPal.`);
  }
}

// Context
class PaymentContext {
  private strategy: PaymentStrategy;

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

  executePayment(amount: number): void {
    this.strategy.pay(amount);
  }
}

// Client
const paymentContext = new PaymentContext();

paymentContext.setStrategy(new CreditCardPayment());
paymentContext.executePayment(100);

paymentContext.setStrategy(new PayPalPayment());
paymentContext.executePayment(200);

Go Implementation

Interface Polymorphism + Explicit Composition

To hide the strategy API from the client and prevent names conflict on multiple type strategies, so it use Explicit Embedding.

Struct Embedding