Strategy Pattern
1. strategyPattern
- 策略模式(strategyPattern): 定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。策略模式是一种对象行为型模式。可以解决选择多种算法情况下,使用 if…else 所带来的复杂和难以维护。
2. 模式分析
- 策略模式是一个比较容易理解和使用的设计模式,策略模式是对算法的封装,它把算法的责任和算法本身分割开,委派给不同的对象管理。
- 策略模式通常把一个系列的算法封装到一系列的策略类里面,作为一个抽象策略类的子类。用一句话来说,就是“准备一组算法,并将每一个算法封装起来,使得它们可以互换”。
- 在策略模式中,应当由客户端自己决定在什么情况下使用什么具体策略角色。
- 策略模式仅仅封装算法,提供新算法插入到已有系统中,以及老算法从系统中“退休”的方便。
- 策略模式并不决定在何时使用何种算法,算法的选择由客户端来决定。-------这在一定程度上提高了系统的灵活性,但是客户端需要理解所有具体策略类之间的区别,以便选择合适的算法,这也是策略模式的缺点之一,在一定程度上增加了客户端的使用难度。
3.代码示例
/*
*Strategy Pattern:策略模式
*/
using System;
namespace Pattern01
{
class Program
{
static void Main(string[] args)
{
Context context = new Context(new ConcreteStrategyA());
context.ContextInterface();
context = new Context(new ConcreteStrategyB());
context.ContextInterface();
context = new Context(new ConcreteStrategyC());
context.ContextInterface();
Console.ReadKey();
}
}
/// <summary>
/// strategy
/// declares an interface common to all supported algorithms.
/// Context uses this interface to call the algorithm defined by a ConcreteStrategy
/// </summary>
abstract class Strategy
{
public abstract void AlgorithmInterface();
}
class ConcreteStrategyA : Strategy
{
public override void AlgorithmInterface()
{
Console.WriteLine("Called ConcreteStrategy A strategy");
}
}
class ConcreteStrategyB : Strategy
{
public override void AlgorithmInterface()
{
Console.WriteLine("called concrete B strategy");
}
}
class ConcreteStrategyC : Strategy
{
public override void AlgorithmInterface()
{
Console.WriteLine("called Concrete C strategy");
}
}
/// <summary>
/// Context
/// is configured with a ConcreteStrategy object
/// maintains a reference to a Strategy object
/// may define an interface that lets Strategy access its data.
/// </summary>
class Context
{
private Strategy _strategy;//算法
public Context(Strategy strategy)
{
this._strategy = strategy;
}
public void ContextInterface()
{
_strategy.AlgorithmInterface();
}
}
}
类图
4. 示例2
/*
*Strategy Pattern:策略模式
*/
using System;
using System.Collections.Generic;
namespace Pattern01
{
class Program
{
static void Main(string[] args)
{
// Three contexts following different strategies
SortList sortList = new SortList();
sortList.Add("Lily");
sortList.Add("Caher");
sortList.Add("Angel");
sortList.Add("Zara");
sortList.SetStrategy(new QuickSort());
sortList.Sort();
sortList.SetStrategy(new ShellSort());
sortList.Sort();
sortList.SetStrategy(new MergeSort());
sortList.Sort();
Console.ReadKey();
}
}
/// <summary>
/// strategy
/// declares an interface common to all supported algorithms.
/// Context uses this interface to call the algorithm defined by a ConcreteStrategy
/// </summary>
interface Strategy
{
void Sort(List<string> lst);
}
class QuickSort : Strategy
{
public void Sort(List<string> lst)
{
Console.WriteLine(".......Quick sort........");
lst.Sort();
}
}
class ShellSort : Strategy
{
public void Sort(List<string> lst)
{
///ShellSort 设计实现
Console.WriteLine("........shell Sort.....");
}
}
class MergeSort : Strategy
{
public void Sort(List<string> lst)
{
//MergeSort 设计实现
Console.WriteLine("..........Merge Sort....");
}
}
/// <summary>
/// Context
/// is configured with a ConcreteStrategy object
/// maintains a reference to a Strategy object
/// may define an interface that lets Strategy access its data.
/// </summary>
class SortList
{
public List<string> _list = new List<string>();
private Strategy _strategy;//算法
public void SetStrategy(Strategy strategy)
{
this._strategy = strategy;
}
public void Sort()
{
//调用排序算法
_strategy.Sort(_list);
foreach (string var in _list)
{
Console.WriteLine(var);
}
}
public void Add(string name)
{
_list.Add(name);
}
}
}
总结
-
The Context maintains a reference to one of the concrete
strategies and communicates with this object only via the
strategy interface. -
The Strategy interface is common to all concrete strategies. It
declares a method the context uses to execute a strategy. -
Concrete Strategies implement different variations of an algorithm
the context uses. -
The context calls the execution method on the linked strategy
object each time it needs to run the algorithm. The context
doesn’t know what type of strategy it works with or how the
algorithm is executed. -
The Client creates a specific strategy object and passes it to
the context. The context exposes a setter which lets clients
replace the strategy associated with the context at runtime.