定义
策略模式(Strategy):它定义了算法家族,分别封装起来,让它们之间可以互相替换
结构图
结构组成
- 策略控制(Context):控制了具体的算法使用,以及负责客户端与算法之间的数据交互
- 抽象策略(Strategy):定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,Context使用这个接口调用不同的算法,一般使用接口或抽象类实现。
- 具体策略:实现Strategy的具体算法
代码实现
生活中有很多例子,每个人做菜的方式不同做出来的菜口味口感都会不同。
/// <summary>
/// 策略控制类---相当于Context
/// </summary>
public class CookContext : Disposable
{
internal ICookStrategy _cookStrategy;
public CookContext(int cookMethod)
{
switch (cookMethod)
{
case 1:
_cookStrategy = new CookStrategy1();
break;
case 2:
_cookStrategy = new CookStrategy2();
break;
default:
break;
}
}
public TomatoEgg Cook()
{
return _cookStrategy.Cook();
}
}
/// <summary>
/// 抽象策略----相当于Strategy
/// </summary>
internal interface ICookStrategy
{
TomatoEgg Cook();
}
/// <summary>
/// 制作番茄炒蛋的方式1
/// </summary>
internal class CookStrategy1 : ICookStrategy
{
public TomatoEgg Cook()
{
var tomatoEgg = new TomatoEgg();
tomatoEgg.Tomato = "带皮番茄";
tomatoEgg.Egg = "普通鸡蛋";
return tomatoEgg;
}
}
/// <summary>
/// 制作番茄炒蛋的方式2
/// </summary>
internal class CookStrategy2 : ICookStrategy
{
public TomatoEgg Cook()
{
var tomatoEgg = new TomatoEgg();
tomatoEgg.Tomato = "去皮番茄";
tomatoEgg.Egg = "农家土鸡蛋";
return tomatoEgg;
}
}
// 调用
CookContext context;
context = new CookContext(1);
var tomatoEgg1 = context.Cook();
tomatoEgg1.Eat();
context = new CookContext(2);
var tomatoEgg2 = context.Cook();
tomatoEgg2.Eat();
优点与缺点
优点:
- 策略类之间可以自由切换,因为所有策略类都实现了的是一个接口
- 扩展更加方便,加入新的算法只需要新增加一个策略类,并且修改策略类算法时不会影响调用方面
- 避免了多重if else语句的出现
缺点:
- 调用方需要知道所有的策略类,才能自行决定调用哪个策略类