In real code, the same kind of task often needs different behavior depending on the situation. When those differences start growing inside one large if/else block, the structure can become messy very quickly. The strategy pattern is one of the classic ways to address that.
In this post, we will cover:
- what the strategy pattern is
- why it helps reduce branching
- when it fits well
- how it connects to object-oriented design principles
The key idea is that the strategy pattern separates “what to do” from “how to do it,” so behavior can be swapped more cleanly.
What is the strategy pattern?
The strategy pattern represents one kind of behavior with multiple interchangeable implementations.
For example:
- card payment strategy
- bank transfer strategy
- points payment strategy
Each one fulfills the same general role in a different way.
Why does it help reduce conditionals?
If every new variation expands one large service with more if/else branches:
- the code becomes harder to read
- testing becomes harder
- adding new behavior touches old code repeatedly
The strategy pattern separates each behavior into its own object so that branching does not keep spreading through the same place.
When does it fit well?
- when behavior variants keep growing
- when the same role has multiple implementations
- when behavior may change at runtime
So it fits especially well when behavior replacement is a real concern.
How does it connect to object-oriented principles?
The strategy pattern often lines up naturally with:
- OCP: new strategies can be added with less modification to stable code
- DIP: code can depend on an abstract role instead of a concrete strategy
- polymorphism: different implementations can stay behind the same message
So the strategy pattern is a very practical example of object-oriented principles becoming concrete structure.
Common misunderstandings
1. Every if/else should become a strategy pattern
Not always. For very small and stable variations, that may be excessive.
2. The strategy pattern only increases class count
It can increase object count, but for frequently changing behavior it often reduces long-term change cost.
3. It is mainly an inheritance pattern
In practice, it is often built more naturally with composition and interfaces.
Simple Example
interface PaymentStrategy {
pay(amount: number): void;
}
class CardPayment implements PaymentStrategy {
pay(amount: number) {
console.log(`Pay ${amount} with card`);
}
}
class PointsPayment implements PaymentStrategy {
pay(amount: number) {
console.log(`Pay ${amount} with points`);
}
}
class CheckoutService {
constructor(private strategy: PaymentStrategy) {}
checkout(amount: number) {
this.strategy.pay(amount);
}
}
const service = new CheckoutService(new CardPayment());
service.checkout(100);
The key point is that CheckoutService depends on PaymentStrategy, not on one concrete payment implementation.
FAQ
Q. Where should beginners try strategy first?
Payment methods, discount rules, sorting behavior, and notification channels are common good examples.
Q. Is strategy pattern the same as polymorphism?
Not exactly, but it is a classic structure that uses polymorphism.
Q. Who chooses the strategy?
Usually a higher-level context or composition layer selects and injects the strategy object.
Read Next
- For the behavior side, continue with the Polymorphism Guide.
- For creation responsibility, read the Factory Pattern Guide.
While AdSense review is pending, related guides are shown instead of ads.
Start Here
Continue with the core guides that pull steady search traffic.
- Middleware Troubleshooting Guide: Redis vs RabbitMQ vs Kafka A practical middleware troubleshooting guide for developers covering when to reach for Redis, RabbitMQ, or Kafka symptoms first, and which problem patterns usually belong to each tool.
- Kubernetes CrashLoopBackOff: What to Check First A practical Kubernetes CrashLoopBackOff troubleshooting guide covering startup failures, probe issues, config mistakes, and what to inspect first.
- Kafka Consumer Lag Increasing: Troubleshooting Guide A practical Kafka consumer lag troubleshooting guide covering what lag usually means, which consumer metrics to check first, and how poll timing, processing speed, and fetch patterns affect lag.
- Kafka Rebalancing Too Often: Common Causes and Fixes A practical Kafka troubleshooting guide covering why consumer groups rebalance too often, what poll timing and group protocol settings matter, and how to stop rebalances from interrupting useful work.
- Docker Container Keeps Restarting: What to Check First A practical Docker restart-loop troubleshooting guide covering exit codes, command failures, environment mistakes, health checks, and what to inspect first.
While AdSense review is pending, related guides are shown instead of ads.