I am here to discuss one of the popular behavioral design patterns, called Strategy. Before going through its implementation, let’s begin by defining it.

As per GOF guys, Strategy Pattern is defined as following.

Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.

Well! Let’s understand what they mean and where this pattern can be fit.

It simply means that this pattern is about having a set of concrete strategies or family of algorithms and choosing the appropriate one at runtime based on the need. Some of the use cases can be classified.

Another example of strategy pattern in .NET framework is Sort method (Array.Sort). It uses insertion, heap, and quicksort at runtime based on the incoming data.

Excerpts from MSDN tell,

This method uses the introspective sort (introsort) algorithm as follows,

Now, let’s see the custom implementation of the pattern. Please have a look at the code map diagram of the demo we have created.

Design patterns

As you can see, Strategy pattern has some key components as given below.

How Strategy pattern works

Let’s understand this by a demo project that we have created. First, create the Strategy interface to start with.

  1. using System.Collections.Generic;
  2. namespace StrategyPatternDemo
  3. {
  4. interface ISortStrategy
  5. {
  6. void Sort<T>(List<T> data);
  7. }
  8. }

As you can see, we have created a generic method to support all types of data. Now, let's create a concrete strategy class to implement the interface we have created above.

  1. using System;
  2. using System.Collections.Generic;
  3. namespace StrategyPatternDemo
  4. {
  5. class HeapSort : ISortStrategy
  6. {
  7. public void Sort<T>(List<T> list)
  8. {
  9. list.Sort();
  10. //We used default sort (.NET Fx) however you can write custom code as well
  11. Console.WriteLine($"After Sort using {this.GetType().Name}:");
  12. }
  13. }
  14. }
  15. //Namespace same as above
  16. class InsertionSort : ISortStrategy
  17. {
  18. public void Sort<T>(List<T> list)
  19. {
  20. list.Sort();
  21. //We used default sort (.NET Fx) however you can write custom code as well
  22. Console.WriteLine($"After Sort using {this.GetType().Name}:");
  23. }
  24. }
  25. //Namespace same as above
  26. class QuickSort : ISortStrategy
  27. {
  28. public void Sort<T>(List<T> list)
  29. {
  30. list.Sort();
  31. //We used default sort (.NET Fx) however you can write custom code as well
  32. Console.WriteLine($"After Sort using {this.GetType().Name}:");
  33. }
  34. }

As you can see in the above code that we have given unique implementations to each sort strategy, although we have used FCL Sort method in all three implementations as objective here is to explain design pattern instead of sorting algorithm, however, you can write your own code in each of them.

So at this point, we are done with strategy and concrete strategies and that is more than half of the code. Now, let’s create the remaining once and here is the code for Context i.e. SortContext.

  1. using System;
  2. using System.Collections.Generic;
  3. using static System.Console;
  4. namespace StrategyPatternDemo
  5. {
  6. class SortContext
  7. {
  8. private ISortStrategy sortStrategy = null;
  9. private void PrintList<T>(List<T> list)
  10. {
  11. foreach (T name in list)
  12. {
  13. Console.Write(name + " ");
  14. }
  15. WriteLine();
  16. }
  17. public void SetSortStrategy(TypeOfData typeOfData)
  18. {
  19. switch (typeOfData)
  20. {
  21. case TypeOfData.DaysInMonth:
  22. this.sortStrategy = new InsertionSort();
  23. break;
  24. case TypeOfData.PassengersInFlight:
  25. this.sortStrategy = new HeapSort();
  26. break;
  27. case TypeOfData.ResidentsInApt:
  28. this.sortStrategy = new QuickSort();
  29. break;
  30. default:
  31. break;
  32. }
  33. }
  34. public void SortAndPrint<T>(List<T> list)
  35. {
  36. WriteLine("Before Sort:");
  37. PrintList(list);
  38. sortStrategy.Sort(list);
  39. PrintList(list);
  40. WriteLine();
  41. }
  42. public enum TypeOfData
  43. {
  44. DaysInMonth,
  45. PassengersInFlight,
  46. ResidentsInApt
  47. }
  48. }
  49. }

As you can see in the class above, i.e., SortContext, we have done a few things as following.

  1. Created an enum to support the type of data to sort.
  2. Setting sort strategy by passing the type of data.
  3. Calling the appropriate Sort method based on the selected strategy in step#2 above.
  4. Calling the reusable Print method to print before and after sort data.

We are almost done. Now, it’s time to set up the client and see something in action. Let’s put the code for it.

  1. using System.Collections.Generic;
  2. using static System.Console;
  3. namespace StrategyPatternDemo
  4. {
  5. class Client
  6. {
  7. static void Main(string[] args)
  8. {
  9. Title = "Strategy Pattern Demo";
  10. SortContext sortContext = new SortContext(); ;
  11. //Sorting days in month
  12. var daysInMonth = new List<int> {5, 1, 17, 27, 12};
  13. sortContext.SetSortStrategy(SortContext.TypeOfData.DaysInMonth);
  14. sortContext.SortAndPrint(daysInMonth);
  15. //Sorting Passengers in flight
  16. var passInFlight = new List<string> {"Kamlesh","Vandana","Prakash","Aradhana","Anay"};
  17. sortContext.SetSortStrategy(SortContext.TypeOfData.PassengersInFlight);
  18. sortContext.SortAndPrint(passInFlight);
  19. //Sorting Residents in Apt
  20. var resiInApt = new List<string> {"Ramsagar", "Siyalali", "Mayank"};
  21. sortContext.SetSortStrategy(SortContext.TypeOfData.ResidentsInApt);
  22. sortContext.SortAndPrint(resiInApt);
  23. }
  24. }
  25. }

And here goes the output of the demo we have developed.

Design patterns

As you can see in the Client class that we are passing three type of data and based on the data, appropriate type of sorting strategy is selected at runtime.

Conclusion

In the article, we have gone through what Strategy pattern is, when and how to use it. Well, it can be used in places where you want to pick one implementation out of some at runtime. You can also download the attached demo project (StrategyPatternDemo.zip) to go through the full source code referred in the article.

Hope you have liked the article. Look forward to your comments/suggestions.

References