Strategy Pattern
Strategy Pattern
Today I present the strategy pattern.
You can read my previous posts about design patterns here:
Structural patterns
Decorator pattern
Proxy pattern
Facade pattern
Adapter pattern
Composite pattern
Bridge pattern
Flyweight pattern
Creational patterns
Singleton pattern
Abstract Factory pattern
Prototype pattern
Factory Method pattern
Builder pattern
Strategy Pattern Introduction
The strategy pattern is one of my favorite patterns.
For every problem in development there are many solutions. There are times
that one solution is preferable then another. But sometimes the other algorithm is
preferable. The strategy pattern helps us to divide an algorithm from a host class
and then move it to another class. By doing so the client can choose which
algorithm will be performed in runtime from a set of algorithms that were
implemented earlier.
Use Cases for the Strategy Pattern
Use the strategy pattern in the following situations:
- There are many classes that differ only in their behavior.
- There are different algorithms that solve a problem and you
want to give the client a way to choose between them.
- The client has no real influence on the algorithms which makes them
a black box.
UML Diagram
Example in C#
The following code will explain how to use the strategy pattern:
#region Strategy
interface IStrategy
{
int Sum(List<int> list);
}
#endregion
#region Concrete Classes
class ConcreteStrategy1 : IStrategy
{
#region IStrategy Members
/// <summary>
/// Calculate the sum of integers in the
/// given list using LINQ
/// </summary>
/// <param name="list">The given integer list</param>
/// <returns>sum of integers in the list</returns>
public int Sum(List<int> list)
{
return list.Sum();
}
#endregion
}
class ConcreteStrategy2 : IStrategy
{
#region IStrategy Members
/// <summary>
/// Calculate the sum of integers in the
/// given list using standard calculation
/// </summary>
/// <param name="list">The given integer list</param>
/// <returns>sum of integers in the list</returns>
public int Sum(List<int> list)
{
int result = 0;
foreach (int value in list)
{
result += value;
}
return result;
}
#endregion
}
#endregion
#region Context
class Context
{
#region Members
IStrategy _strategy;
#endregion
#region Ctor
/// <summary>
/// Construct a new Context object with
/// the given strategy.
/// </summary>
/// <param name="strategy">The given strategy</param>
public Context(IStrategy strategy)
{
_strategy = strategy;
}
#endregion
#region Methods
public void PerformCalculation(List<int> list)
{
Console.WriteLine(string.Format("The list's sum is {0}",
_strategy.Sum(list)));
}
#endregion
}
#endregion
The example is simple I use an interface to define the wanted strategy.
The algorithm I use calculate the sum of an integer list. I built two concrete
classes. One concrete use LINQ for the calculation and the other use standard
array sum. The Context class gets the strategy in its constructor and use it in the
PerformCalculation method. The Context client is responsible to deliver the
relevant strategy. The example is naive but it shows how to use the pattern.
Summary
The strategy pattern is very useful pattern. I use it a lot when I have to
choose from a set of solutions in runtime. The implementation of the
pattern is simple and the gain from it is high.
The next post will explain in details how to use the iterator pattern.