The Strategy design pattern is a behavioral design pattern that allows us to define different functionalities, put each functionality in a separate class and make their objects interchangeable.

In other words, we have a main Context object that holds a reference towards a Strategy object and delegates it by executing its functionality. If we want to change the way the Context performs its work, we can just replace the current Strategy object with another one.

So without further ado, let’s dive dipper into the Strategy design pattern implementation.

The source code is available at the Strategy Design Pattern – Source Code.

For the main page of this series check out C# Design Patterns.

This article is divided into the following sections:

Strategy Design Pattern Structure

As we stated above, the Strategy design pattern consists of the Context object which maintains the reference towards the strategy object. But it is not the only part of the puzzle. For the complete implementation, we need the Strategy object (interface) to define a way for the Context object to execute the strategy and the Concrete Strategies objects which implements the Strategy interface.

The Strategy design pattern is quite common in the C# language due to its various uses to provide changing behavior of a class without modifying it. This complies with the rules of the Open Closed Principle, which we talked about in one of our previous articles.

Implementation of the Strategy Design Pattern

To implement the Strategy pattern, we are going to reuse an example from our Open Closed Principle article.

So, the main task is to calculate the total cost for the developer’s salaries, but for the different developer level, the salary is calculated differently. Now, we are going to modify that example by introducing the Strategy design pattern.

So let’s start with the DeveloperLevel enumeration and a simple DeveloperReport object:

To continue on, let’s create the Strategy interface named ISalaryCalculator:

Now what we need is the concrete strategy objects which will accept all the reports and calculate the total salary for the required developer levels:

As we can see, for the senior developers, we are adding a 20% bonus to the salary. Additionally, we have separated our calculation logic for the different developer levels and made easier to add calculation logic for the medior developers for example. All we would have to do is to add an additional strategy object which implements the ISalaryCalculator interface.

Once we have the strategy objects, we need the context object in our implementation:

In this context object, we provide initialization of the strategy object with the constructor in a compile-time or with the SetCalculator method in the application’s runtime. Furthermore, the Calculate method just executes the strategy object functionality.

So, to connect all the dots together, let’s modify the Program.cs class:

This should be our result:

Strategy Design Pattern - Complete

When Should We Use the Strategy Design Pattern

We should use this pattern whenever we have different variations for some functionality in an object and we want to switch from one variation to another in a runtime. Furthermore, if we have similar classes in our project that only differ on how they execute some behavior, the Strategy pattern should be the right choice for us.

We should consider introducing this pattern in situations where a single class has multiple conditions over different variations of the same functionality. That’s because the Strategy pattern lets us extract those variations into separate classes (concrete strategies). Then we can invoke them into the context class.

Conclusion

As you can see, implementing the Strategy design pattern isn’t hard or complex at all.

It makes our code more readable and easier to maintain. Yes, it requires an implementation of additional classes in the project, but that’s the price worth paying for.

So, we have learned:

  • What is the Strategy design pattern
  • How to implement it in C#
  • And, when to use it

If you have enjoyed reading this article and if you would like to receive the notifications about the freshly published .NET Core content we encourage you to subscribe to our blog.