Strategy Pattern
The Strategy Pattern is a behavioral design pattern that lets you define a family of algorithms, put each of them into a separate class, and make their objects interchangeable.
1. The Core Concept
The main idea is to separate the behavior (algorithm) from the class that uses it (context). This allows you to swap algorithms at runtime without modifying the context.
- Context: The class that maintains a reference to a Strategy object. It delegates the work to the strategy.
- Strategy Interface: A common interface for all supported algorithms.
- Concrete Strategies: Different implementations of the algorithm.
2. Analogy: Navigation App
Imagine a navigation app.
- You want to go to the airport.
- You can choose different strategies: Car, Walking, Public Transport.
- The destination is the same, but the algorithm for calculating the route is different. The app (Context) can switch between these strategies instantly based on user choice.
3. Example (TypeScript)
Let's implement a simple payment system.
// The Strategy Interface
interface PaymentStrategy {
pay(amount: number): void;
}
// Concrete Strategy 1
class CreditCardPayment implements PaymentStrategy {
private cardNumber: string;
constructor(cardNumber: string) {
this.cardNumber = cardNumber;
}
pay(amount: number): void {
console.log(`Paid ${amount} using Credit Card ${this.cardNumber}`);
}
}
// Concrete Strategy 2
class PayPalPayment implements PaymentStrategy {
private email: string;
constructor(email: string) {
this.email = email;
}
pay(amount: number): void {
console.log(`Paid ${amount} using PayPal account ${this.email}`);
}
}
// The Context
class ShoppingCart {
private paymentStrategy: PaymentStrategy;
constructor(strategy: PaymentStrategy) {
this.paymentStrategy = strategy;
}
// Allow changing strategy at runtime
setPaymentStrategy(strategy: PaymentStrategy) {
this.paymentStrategy = strategy;
}
checkout(amount: number) {
this.paymentStrategy.pay(amount);
}
}
// Usage
const cart = new ShoppingCart(new CreditCardPayment("1234-5678"));
cart.checkout(100); // Output: Paid 100 using Credit Card 1234-5678
cart.setPaymentStrategy(new PayPalPayment("user@example.com"));
cart.checkout(200); // Output: Paid 200 using PayPal account user@example.com
4. Pros and Cons
| Pros | Cons |
|---|---|
| Open/Closed Principle: You can introduce new strategies without changing the context. | Complexity: Increases the number of classes in the application. |
| Runtime Switching: You can swap algorithms inside an object at runtime. | Client Awareness: The client must know the difference between strategies to select the right one. |
| Isolation: Implementation details of an algorithm are isolated from the code that uses it. |
programming/design-patterns programming/composition-over-inheritance programming/solid-principles