 |
Define a family of algorithms, encapsulate each one, and make them interchangeable.
Strategy lets the algorithm vary independently from clients that use it.
Frequency of use: medium high
|
|
 |
The classes and/or objects participating in this pattern are:
- Strategy (SortStrategy)
- declares an interface common to all supported algorithms. Context
uses this interface to call the algorithm defined by a ConcreteStrategy
- ConcreteStrategy (QuickSort, ShellSort, MergeSort)
- implements the algorithm using the Strategy interface
- Context (SortedList)
- is configured with a ConcreteStrategy
object
- maintains a reference to a Strategy
object
- may define an interface that lets Strategy access its data.
This structural code demonstrates the Strategy pattern which encapsulates functionality in the
form of an object. This allows clients to dynamically change algorithmic
strategies.
Show code
|
// Strategy pattern -- Structural example
|
|
using System;
namespace DoFactory.GangOfFour.Strategy.Structural
{
// MainApp test application
class MainApp
{
static void Main()
{
Context context;
// Three contexts following different strategies
context = new Context(new ConcreteStrategyA());
context.ContextInterface();
context = new Context(new ConcreteStrategyB());
context.ContextInterface();
context = new Context(new ConcreteStrategyC());
context.ContextInterface();
// Wait for user
Console.Read();
}
}
// "Strategy"
abstract class Strategy
{
public abstract void AlgorithmInterface();
}
// "ConcreteStrategyA"
class ConcreteStrategyA : Strategy
{
public override void AlgorithmInterface()
{
Console.WriteLine(
"Called ConcreteStrategyA.AlgorithmInterface()");
}
}
// "ConcreteStrategyB"
class ConcreteStrategyB : Strategy
{
public override void AlgorithmInterface()
{
Console.WriteLine(
"Called ConcreteStrategyB.AlgorithmInterface()");
}
}
// "ConcreteStrategyC"
class ConcreteStrategyC : Strategy
{
public override void AlgorithmInterface()
{
Console.WriteLine(
"Called ConcreteStrategyC.AlgorithmInterface()");
}
}
// "Context"
class Context
{
Strategy strategy;
// Constructor
public Context(Strategy strategy)
{
this.strategy = strategy;
}
public void ContextInterface()
{
strategy.AlgorithmInterface();
}
}
}
|
Output
Called ConcreteStrategyA.AlgorithmInterface()
Called ConcreteStrategyB.AlgorithmInterface()
Called ConcreteStrategyC.AlgorithmInterface()
|
This real-world code demonstrates the Strategy pattern which encapsulates sorting algorithms in the
form of sorting objects. This allows clients to dynamically change sorting
strategies including Quicksort, Shellsort, and Mergesort.
Show code
|
// Strategy pattern -- Real World example
|
|
using System;
using System.Collections;
namespace DoFactory.GangOfFour.Strategy.RealWorld
{
// MainApp test application
class MainApp
{
static void Main()
{
// Two contexts following different strategies
SortedList studentRecords = new SortedList();
studentRecords.Add("Samual");
studentRecords.Add("Jimmy");
studentRecords.Add("Sandra");
studentRecords.Add("Vivek");
studentRecords.Add("Anna");
studentRecords.SetSortStrategy(new QuickSort());
studentRecords.Sort();
studentRecords.SetSortStrategy(new ShellSort());
studentRecords.Sort();
studentRecords.SetSortStrategy(new MergeSort());
studentRecords.Sort();
// Wait for user
Console.Read();
}
}
// "Strategy"
abstract class SortStrategy
{
public abstract void Sort(ArrayList list);
}
// "ConcreteStrategy"
class QuickSort : SortStrategy
{
public override void Sort(ArrayList list)
{
list.Sort(); // Default is Quicksort
Console.WriteLine("QuickSorted list ");
}
}
// "ConcreteStrategy"
class ShellSort : SortStrategy
{
public override void Sort(ArrayList list)
{
//list.ShellSort(); not-implemented
Console.WriteLine("ShellSorted list ");
}
}
// "ConcreteStrategy"
class MergeSort : SortStrategy
{
public override void Sort(ArrayList list)
{
//list.MergeSort(); not-implemented
Console.WriteLine("MergeSorted list ");
}
}
// "Context"
class SortedList
{
private ArrayList list = new ArrayList();
private SortStrategy sortstrategy;
public void SetSortStrategy(SortStrategy sortstrategy)
{
this.sortstrategy = sortstrategy;
}
public void Add(string name)
{
list.Add(name);
}
public void Sort()
{
sortstrategy.Sort(list);
// Display results
foreach (string name in list)
{
Console.WriteLine(" " + name);
}
Console.WriteLine();
}
}
}
|
Output
QuickSorted list
Anna
Jimmy
Samual
Sandra
Vivek
ShellSorted list
Anna
Jimmy
Samual
Sandra
Vivek
MergeSorted list
Anna
Jimmy
Samual
Sandra
Vivek
|
This .NET optimized code demonstrates the
same real-world situation as above but uses modern, built-in .NET features.
Show code
|
// Strategy pattern -- .NET optimized
|
See our Singleton page for a .NET optimized code sample.
|
|
|