Behavioral Design Pattern: Strategy

Explore the Strategy pattern in-depth using C# as an example.

Avinash Dhumal
Cloud Native Daily
4 min readJul 8, 2023

--

AI Generated Image

Introduction

In the world of software development, design patterns play a crucial role in ensuring maintainable, scalable, and flexible code. One such pattern is the Strategy design pattern, which allows for dynamic behavior selection at runtime. In this article, we will explore the Strategy pattern in-depth using C# as an example. We will also try to understand the pros and cons of using the Strategy pattern in this article. The aim is to explain the concept in a simple and accessible manner, even for beginners.

Understanding the Strategy Design Pattern

The Strategy design pattern falls under the behavioral design pattern category. It enables you to define a family of algorithms, encapsulate each one as a separate class, and make them interchangeable just like an OPEN CLOSED SOLID DESIGN PRINCIPLE. This pattern allows the algorithms to vary independently from the clients that use them, promoting code reusability, flexibility, and maintainability.

Before we jump on to the example, let’s see the pros and cons of using the Strategy Pattern in your applications.

Fig: Pros and Cons

Let's illustrate the Strategy pattern with a relatable example: calculating grades for students. We will assume the following grading system:

  • Above 90%: A grade
  • 80% to 89%: B grade
  • 70% to 79%: C grade
  • Below 70%: D grade

Implementing the Strategy Design Pattern in C#

To implement the Strategy pattern, we need to follow these steps:

Fig: Class Diagram

Step 1: Define the Context
The Context represents the object that uses different strategies. In our example, the Context is the Student class responsible for calculating the grade. It will have a reference to the current strategy object.

public class Student
{
private IGradeCalculator _gradeCalculator;

public Student(IGradeCalculator gradeCalculator)
{
_gradeCalculator = gradeCalculator;
}

public string CalculateGrade(double percentage)
{
return _gradeCalculator.CalculateGrade(percentage);
}
}

Step 2: Define the Strategy Interface
The Strategy interface declares a method that all concrete strategies must implement. In our case, it's the IGradeCalculator interface.

public interface IGradeCalculator
{
string CalculateGrade(double percentage);
}

Step 3: Implement Concrete Strategies
Concrete strategies are the individual algorithms encapsulated in separate classes. They all implement the IGradeCalculator interface.

public class GradeCalculatorA : IGradeCalculator
{
public string CalculateGrade(double percentage)
{
if (percentage > 90)
return "A";

return null; // Return null for unrecognized grades
}
}

public class GradeCalculatorB : IGradeCalculator
{
public string CalculateGrade(double percentage)
{
if (percentage >= 80 && percentage <= 89)
return "B";

return null;
}
}

public class GradeCalculatorC : IGradeCalculator
{
public string CalculateGrade(double percentage)
{
if (percentage >= 70 && percentage <= 79)
return "C";

return null;
}
}

public class GradeCalculatorD : IGradeCalculator
{
public string CalculateGrade(double percentage)
{
if (percentage < 70)
return "D";

return null;
}
}

Step 4: Using the Strategy Pattern
Now, let's use the Strategy pattern to calculate the grade for a student.

static void Main(string[] args)
{
Student student = new Student(new GradeCalculatorA());

double percentage = 95.5;
string grade = student.CalculateGrade(percentage);
Console.WriteLine($"Grade: {grade}");
}
Output: Grade: A

In the above example, we instantiated a Student object and passed an instance of GradeCalculatorA as the strategy. We then called the CalculateGrade method on the student object, which dynamically executed the algorithm implemented in GradeCalculatorA.

Conclusion

The Strategy design pattern is a powerful technique for implementing algorithms in a flexible and maintainable way. It allows us to encapsulate different algorithms and choose the appropriate one dynamically at runtime. By following the steps outlined in this article and using C# as an example, we have demonstrated how the Strategy pattern can be applied to calculate student grades.

Remember, design patterns are tools that improve code quality and maintainability. Understanding and applying them will make you a more proficient and effective software developer.

If you enjoy the content I create and would like to show your appreciation, you can buy me a coffee!

--

--

Avinash Dhumal
Cloud Native Daily

13+ years of software architect, design, development, management, and support experience in Microsoft technologies using Azure & AWS Cloud services.