定义/意图:定义一组算法并对其封装,使其可以互相替换,并根据所处上下文,使用不同的算法或业务规则
问题:对所需要算法的选择取决于发出请求的客户或要处理的数据。如果只有一些不会变化的算法,则不需要Strategy模式
解决方案:把算法的选择和算法的实现分离,允许根据上下文进行选择
参与者与协作者:Strategy基类指定不同算法的公共接口,具体Strategy实现不同的算法,上下文通过类型为Strategy的引用使用具体的Strategy实现。Context将来自客户的请求发给Strategy。
效果:可以不使用switch或条件语句,但必须以相同的方式调用所有的算法,客户需要自己选择所用具体的算法,并转给Context对象
实现:让使用算法的类(Context)包含一个抽象类(Strategy),此抽象类有一个抽象方法指定如何调用算法,每个派生类按需要实现算法。
下面是一个排序算法的示例,不同的具体的排序算法做为不同的策略,可以被用户在上下文中调用,以完成相同的排序功能。
using System;
using System.Collections.Generic;
namespace Strategy
{
/// <summary>
/// MainApp startup class for Real-World
/// Strategy Design Pattern.
/// </summary>
class MainApp
{
/// <summary>
/// Entry point into console application.
/// </summary>
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.ReadKey();
}
}
/// <summary>
/// The 'Strategy' abstract class
/// </summary>
abstract class SortStrategy
{
public abstract void Sort(List<string> list);
}
/// <summary>
/// A 'ConcreteStrategy' class
/// </summary>
class QuickSort : SortStrategy
{
public override void Sort(List<string> list)
{
list.Sort(); // Default is Quicksort
Console.WriteLine("QuickSorted list ");
}
}
/// <summary>
/// A 'ConcreteStrategy' class
/// </summary>
class ShellSort : SortStrategy
{
public override void Sort(List<string> list)
{
//list.ShellSort(); not-implemented
Console.WriteLine("ShellSorted list ");
}
}
/// <summary>
/// A 'ConcreteStrategy' class
/// </summary>
class MergeSort : SortStrategy
{
public override void Sort(List<string> list)
{
//list.MergeSort(); not-implemented
Console.WriteLine("MergeSorted list ");
}
}
/// <summary>
/// The 'Context' class
/// </summary>
class SortedList
{
private List<string> _list = new List<string>();
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);
// Iterate over list and display results
foreach (string name in _list)
{
Console.WriteLine(" " + name);
}
Console.WriteLine();
}
}
}
在实际使用中,Strategy模式可能会增量量的数量,主要是互相替代的算法过多,这时如果使用C++的话,可以把所有具体策略的头文件包含在抽象类Strategy中,而把具体策略类的实现都放在Strategy的CPP文件中。
策略模式体现了面向对象的“对接口编辑”,“多用组合,少用继承”,“封装变化”等思想,而且遵循诸如“依赖倒置”,“开放封装”,“类型一致”等面向对象的设计原则。