- defines a family of algorithms,
- encapsulates each algorithm, and
- makes the algorithms interchangeable within that family.
UML Class Diagrams
Figure 1 and Figure 2 show the class diagrams of strategy pattern.
Figure 1: Strategy pattern in LePUS3
Figure 2: Strategy Pattern in UML
Participants
Class/Interface | Description |
---|---|
Context | A class that sets in between the client and the ConcreteStrategy. It handles the communication between the 2. The client cannot directly instantiate the strategy. It must notify the Context on what ConcreteStrategy to be used. |
Strategy | An interface that defines the contracts to be use by the ConcreteStrategy. |
ConcreteStrategyA, ConcreteStrategyB | A concrete class that implements the Strategy. They contains the |
Client | It consumes the pattern. |
To explain this better i believe that reinforcing it with an example is the best way to do. We are going to build an application that sorts numbers with different algorithms.
The Problem
How to create sorting application that adheres to the following:
- Use single interface to use different kinds of sort algorithm.
- The client program will not breakdown even thought there are updates or additional algorithms.
- Encapsulate the sorting logic.
Strategy Design Pattern
The Source Code
The Project Structure
We are going to use Console Application in C# using Visual Studio 2013. We need 5 classes to build this application. Figure 3 show the Project of what we will be building. Figure 4 shows the UML Diagram.
Figure 3: The Project Structure
Figure 4: The UML Class Diagram

Class Mapping
The interface and classes used in relation to the pattern is as follows:
- Context - SortContext.cs
- Strategy - ISortStrategy.cs
- ConcreteStategies - BubbleSort.cs, HeapSort.cs
- Client - Program.cs
- The ISortStrategy interface has a SortNumbers method to be implemented by the BubbleSort and HeapSort classses. It will be used in the SortContext class as a property. The reasons we use interface is for extensibility and testability.
- SortContext class is base class that controls the flow of information between the client and the sort algorithms. It talks to the client, takes what kind of algorithm the client requested, look for the sort algorithm and sends back the output.
- BubbleSort and HeapSort are concrete classes that contains sort algorithms.
- The Program.cs is the client program.
In order to retain the base class untouched when we add new sort algorithm, we will use Dependency Injection Principle(DIP). We will inject the new instance of algorithm in the client side instead of hard coding it in the SortContext class. In this situation Property Injection is used.
The Codes
ISortStrategy.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
namespace StrategyPattern.Interface | |
{ | |
public interface ISortStrategy | |
{ | |
List<int> SortNumbers(List<int> NumbersToSort); | |
} | |
} |
BubbleSort.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using StrategyPattern.Interface; | |
using System.Collections.Generic; | |
namespace StrategyPattern.SortAlgorithms | |
{ | |
public class BubbleSort : ISortStrategy | |
{ | |
public List<int> SortNumbers(List<int> NumbersToSort) | |
{ | |
int temp; | |
for (int topIndex = 1; topIndex <= NumbersToSort.Count; topIndex++) | |
for (int bottomIndex = 0; bottomIndex < NumbersToSort.Count - topIndex; bottomIndex++) | |
if (NumbersToSort[bottomIndex] > NumbersToSort[bottomIndex + 1]) | |
{ | |
temp = NumbersToSort[bottomIndex]; | |
NumbersToSort[bottomIndex] = NumbersToSort[bottomIndex + 1]; | |
NumbersToSort[bottomIndex + 1] = temp; | |
} | |
return NumbersToSort; | |
} | |
} | |
} |
HeapSort.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using StrategyPattern.Interface; | |
using System.Collections.Generic; | |
using System.Linq; | |
namespace StrategyPattern.SortAlgorithms | |
{ | |
public class HeapSort : ISortStrategy | |
{ | |
public List<int> SortNumbers(List<int> NumbersToSort) | |
{ | |
int list_size = NumbersToSort.Count(); | |
int i, temp; | |
for (i = (list_size / 2) - 1; i >= 0; i--) siftDown(NumbersToSort, i, list_size-1); | |
for (i = list_size - 1; i >= 1; i--) | |
{ | |
temp = NumbersToSort[0]; | |
NumbersToSort[0] = NumbersToSort[i]; | |
NumbersToSort[i] = temp; | |
siftDown(NumbersToSort, 0, i - 1); | |
} | |
return NumbersToSort; | |
} | |
private void siftDown(List<int> NumbersToSort, int root, int bottom) | |
{ | |
int done, maxChild, temp; | |
done = 0; | |
while ((root * 2 <= bottom) && (done == 0)) | |
{ | |
if (root * 2 == bottom) | |
maxChild = root * 2; | |
else if (NumbersToSort[root * 2] > NumbersToSort[root * 2 + 1]) | |
maxChild = root * 2; | |
else | |
maxChild = root * 2 + 1; | |
if (NumbersToSort[root] < NumbersToSort[maxChild]) | |
{ | |
temp = NumbersToSort[root]; | |
NumbersToSort[root] = NumbersToSort[maxChild]; | |
NumbersToSort[maxChild] = temp; | |
root = maxChild; | |
} | |
else | |
done = 1; | |
} | |
} | |
} | |
} |
SortContext.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using StrategyPattern.Interface; | |
using System.Collections.Generic; | |
namespace StrategyPattern.Context | |
{ | |
public class SortContext | |
{ | |
public List<int> NumbersToSort { get; set; } | |
public ISortStrategy SortAlgorithm { set; get; } | |
public List<int> GetSortedNumbers() | |
{ | |
return SortAlgorithm.SortNumbers(this.NumbersToSort); | |
} | |
} | |
} |
Program.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using StrategyPattern.Context; | |
using StrategyPattern.SortAlgorithms; | |
namespace StrategyPattern | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
SortContext MasterSorter = new SortContext(); | |
MasterSorter.SortAlgorithm = new BubbleSort(); | |
MasterSorter.NumbersToSort = new List<int> {43,434,23,99,33,23,323 }; | |
List<int> SortedFromBubble = MasterSorter.GetSortedNumbers(); | |
MasterSorter.SortAlgorithm = new HeapSort(); | |
MasterSorter.NumbersToSort = new List<int> { 43, 434, 23, 99, 33, 23, 323}; | |
List<int> SortedFromHeap = MasterSorter.GetSortedNumbers(); | |
Console.WriteLine("Sorted from Bubble...."); | |
Console.WriteLine("=============================================="); | |
foreach (int number in SortedFromBubble) | |
{ | |
Console.Write(string.Format("{0}, ", number)); | |
} | |
Console.WriteLine(""); | |
Console.WriteLine(""); | |
Console.WriteLine("Sorted from Heap...."); | |
Console.WriteLine("=============================================="); | |
foreach (int number in SortedFromHeap) | |
{ | |
Console.Write(string.Format("{0}, ", number)); | |
} | |
Console.WriteLine(""); | |
Console.WriteLine(""); | |
} | |
} | |
} |
Your thoughts!