🤔 What Is the Strategy Pattern?
The Strategy Pattern is a behavioural design pattern that allows you to define a family of algorithms, encapsulate each one and make them interchangeable at runtime. Instead of hardcoding behaviour into a class, the pattern enables selecting behaviour dynamically.
Think of it like changing the route calculation method in a navigation app from “shortest” to “fastest” or “no tolls”. All without changing the app itself.
🧭 When to Use It
Use the Strategy Pattern when:
You have multiple ways to perform an action and the best one should be chosen at runtime
You want to eliminate conditional logic that selects different algorithms
You need to allow users or systems to customize how a task is performed
Common examples:
Payment processing (credit card, PayPal, crypto)
Sorting data using different algorithms
Logging strategies for file, console or cloud
🛠️ How It Works
The pattern includes:
A Strategy Interface that defines a behaviour
One or more Concrete Strategies implementing the interface
A Context that uses a strategy and delegates the work to it
C# Example: Sorting Strategies
// Strategy Interface
public interface ISortStrategy
{
void Sort(List<int> list);
}
// Concrete Strategy 1
public class BubbleSort : ISortStrategy
{
public void Sort(List<int> list)
{
Console.WriteLine("Using Bubble Sort");
// Simulate sorting
}
}
// Concrete Strategy 2
public class QuickSort : ISortStrategy
{
public void Sort(List<int> list)
{
Console.WriteLine("Using Quick Sort");
// Simulate sorting
}
}
// Context
public class SortContext
{
private ISortStrategy _strategy;
public SortContext(ISortStrategy strategy)
{
_strategy = strategy;
}
public void SetStrategy(ISortStrategy strategy)
{
_strategy = strategy;
}
public void ExecuteSort(List<int> list)
{
_strategy.Sort(list);
}
}
Usage
var list = new List<int> { 3, 1, 4, 1, 5 };
var context = new SortContext(new BubbleSort());
context.ExecuteSort(list);
context.SetStrategy(new QuickSort());
context.ExecuteSort(list);
✅ Advantages
Promotes open/closed principle: add new strategies without modifying existing code
Eliminates messy
if-else
orswitch
statementsMakes unit testing individual algorithms easier
Encourages composition over inheritance
❌ Disadvantages
Can introduce extra complexity if overused
Client must be aware of different strategies and choose appropriately
May lead to too many small classes
🧪 Testing Benefits
You can test each strategy in isolation
Context logic becomes simpler and easier to mock
Easier to inject strategies using dependency injection
🌍 Real-World Use Cases
Authentication: Choose between OAuth, JWT or SAML providers
Compression tools: Select between ZIP, GZip or custom compression
Pricing engines: Apply seasonal, promotional or loyalty-based discounts
Game development: Different AI behaviors for enemy movement
🔗 Related Patterns
State: Similar structure but focuses on object state transitions
Command: Encapsulates a request as an object, while Strategy encapsulates an algorithm
Decorator: Adds behavior to objects without modifying their class
🎯 Final Thoughts
The Strategy Pattern gives you total control over behavior while keeping your codebase clean and extensible. It is one of the most practical patterns you can apply, especially when business logic is expected to vary or grow over time.