Understanding the Strategy Design Pattern in C#
Dennis John
Innovative Product Owner | Agile Expert | Certified Scrum Master | SAFE? PO/PM | Passionate Solution Architect Transforming Ideas into Reality!
As I was trying to refresh my knowledge on design patterns, I spent some time revisiting the Strategy Pattern and found it to be one of the most practical and widely used patterns. I thought of sharing my thoughts here, as it can help a wider audience understand how to apply it effectively in C#.
The Strategy Pattern is a behavioural design pattern that enables selecting an algorithm dynamically at runtime. Instead of implementing multiple variations of a behaviour inside a single class (which leads to tight coupling), this pattern encapsulates different behaviours in separate classes, making the system more scalable and maintainable.
In this article, I will:
Whether you're new to design patterns or looking to refine your understanding, this deep dive into the Strategy Pattern will provide valuable insights. Let’s get started! ??
Why Use the Strategy Pattern?
Software applications often need to support multiple variations of a behaviour. Without a structured approach, this can lead to:
The Strategy Pattern solves this by defining a family of algorithms, encapsulating them in separate classes, and making them interchangeable.
Pros and Cons of the Strategy Pattern
? Pros
? Cons
C# Implementation: Strategy Pattern with Students and Subjects
Let’s consider a Student who can choose a Study Strategy for different subjects.
Step 1: Define the Strategy Interface
Each study method will implement this interface:
public interface IStudyStrategy
{
void Study(string subject);
}
Step 2: Implement Concrete Strategies
Each strategy represents a different study approach.
public class IntensiveStudyStrategy : IStudyStrategy
{
public void Study(string subject)
{
Console.WriteLine($"Studying {subject} intensively for long hours with deep focus.");
}
}
public class CasualStudyStrategy : IStudyStrategy
{
public void Study(string subject)
{
Console.WriteLine($"Studying {subject} casually with short breaks and light reading.");
}
}
public class GroupStudyStrategy : IStudyStrategy
{
public void Study(string subject)
{
Console.WriteLine($"Studying {subject} in a group discussion format.");
}
}
领英推荐
Step 3: Create the Context Class (Student)
The Student class will hold a reference to a strategy and delegate the Study action to the selected strategy.
public class Student
{
private IStudyStrategy _studyStrategy;
public void SetStudyStrategy(IStudyStrategy studyStrategy)
{
_studyStrategy = studyStrategy;
}
public void StudySubject(string subject)
{
if (_studyStrategy == null)
{
Console.WriteLine("No study strategy selected. Defaulting to self-study.");
}
else
{
_studyStrategy.Study(subject);
}
}
}
Dynamic Strategy Selection
Instead of hardcoding the strategy in Main(), let’s allow user input or configuration-based selection.
Step 4: User Input-Based Selection
using System;
class Program
{
static void Main()
{
Student student = new Student();
Console.WriteLine("Choose your study strategy:");
Console.WriteLine("1 - Intensive Study");
Console.WriteLine("2 - Casual Study");
Console.WriteLine("3 - Group Study");
Console.Write("Enter your choice: ");
string choice = Console.ReadLine();
IStudyStrategy selectedStrategy = GetStrategy(choice);
student.SetStudyStrategy(selectedStrategy);
student.StudySubject("Mathematics"); // Example: applying the strategy to Mathematics
}
static IStudyStrategy GetStrategy(string choice)
{
return choice switch
{
"1" => new IntensiveStudyStrategy(),
"2" => new CasualStudyStrategy(),
"3" => new GroupStudyStrategy(),
_ => new CasualStudyStrategy() // Default strategy
};
}
}
Output (User enters "1")
Studying Mathematics intensively for long hours with deep focus.
Step 5: Configuration-Based Selection (Enterprise Applications)
In real-world applications, the strategy should be selected dynamically from a configuration file, API, or database.
Using appsettings.json (For ASP.NET Core)
{
"StudyStrategy": "IntensiveStudy"
}
Reading the Configuration in Code
using Microsoft.Extensions.Configuration;
public class Program
{
public static void Main(string[] args)
{
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.Build();
string strategyName = configuration["StudyStrategy"];
IStudyStrategy studyStrategy = GetStrategy(strategyName);
Student student = new Student();
student.SetStudyStrategy(studyStrategy);
student.StudySubject("Physics");
}
static IStudyStrategy GetStrategy(string strategyName)
{
return strategyName switch
{
"IntensiveStudy" => new IntensiveStudyStrategy(),
"CasualStudy" => new CasualStudyStrategy(),
"GroupStudy" => new GroupStudyStrategy(),
_ => new CasualStudyStrategy()
};
}
}
Now, modifying the strategy is as simple as updating appsettings.json!
This makes the application more scalable and maintainable.
Final Thoughts
? Best Use Cases for the Strategy Pattern
? When NOT to Use
Conclusion
The Strategy Pattern is a powerful way to encapsulate behaviours into separate classes and switch them dynamically at runtime.
This pattern provides flexibility, modularity, and scalability while keeping the core logic clean and maintainable.
Thanks for sharing your thoughts on the Strategy Pattern in .NET! It's such a valuable design approach for creating flexible architecture. What other patterns do you find particularly useful?