定义:(Strategy Pattern)
定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。
类图:
策略模式通用类图启示:
逝者如斯夫,不舍昼夜,眨眼间2016又要翻页了。回顾2016,也算是是浓墨重彩的一笔。所以赶在元旦假期到来之际,筹划一次元旦小旅行,来迎接崭新的2017。
旅行之前要现做预算做计划啊。
经过一番讨论,终于出来了三个方案:
- 桂林山水甲天下,心向往之
- 爬回长城充好汉
预算五千大洋。
出行方案肯定要与时间、天气、预算息息相关。
考虑到元旦只有三天时间,那方案2时间够呛,所以取消。
剩下两个方案,二选一就容易多了。
但是未知的天气因素,得准备个备份方案:逛街看电影包饺子
读到这里,你应该就知道我想说什么了吧。
两个方案三种策略,咱策略模式来瞧瞧。
代码:
先来定义旅游策略。
/// <summary>
/// 旅行策略类
/// </summary>
public abstract class TravelStrategy
{
/// <summary>
/// 目的地
/// </summary>
public string PlanName { get; set; }
/// <summary>
/// 预算
/// </summary>
public int Budget { get; set; }
/// <summary>
/// 旅游计划
/// </summary>
public abstract void TravelPlan();
}
再来看看具体桂林游方案。
public class GuangxiTravel : TravelStrategy
{
public GuangxiTravel()
{
this.PlanName = "广西桂林山水甲天下,心向往之!";
}
public override void TravelPlan()
{
Console.WriteLine("广西旅游计划:");
Console.WriteLine(string.Format("计划名称:{0}预算:{1}", this.PlanName, this.Budget));
if (this.Budget >= 4000)
{
Console.WriteLine("选择高铁出行!");
}
else
{
Console.WriteLine("选择大巴出行!");
}
}
}
这里根据预算,定义了具体的两种出行方案。
最后上我们的备用策略:
public class BackupTravel : TravelStrategy
{
public BackupTravel()
{
this.PlanName = "逛街看电影包饺子!";
}
public override void TravelPlan()
{
Console.WriteLine("备用旅游计划:");
Console.WriteLine(string.Format("计划名称:{0}", this.PlanName));
}
}
天气枚举
enum Weather
{
Sunny =1,
Rain = 2
}
场景类
TravelStrategy travelPlan = null;
Weather weather = (Weather)(new Random().Next(1,3));
switch (weather)
{
case Weather.Rain:
Console.WriteLine("天气糟糕");
travelPlan = new BackupTravel() ;
break;
case Weather.Sunny:
Console.WriteLine("天气晴好");
travelPlan = new GuangxiTravel() { Budget = 3000 };
break;
}
travelPlan.TravelPlan();
Console.ReadLine();
运行结果
总结:
策略模式是一个非常简单的模式。它在项目中使用得非常多,但它单独使用的地方就比较少了,因为它有致命缺陷:所有的策略都需要暴露出去,这样才方便客户端决定使用哪一个策略。
优缺点:
优点
算法可自由切换,扩展性良好
缺点
算法需要暴露,违反迪米特法则,需要与其他设计模式混用来解决上层模块对策略的直接依赖。
应用场景:
多个类只有在算法或行为上稍有不同的场景;
算法需要自由切换的场景;
需要屏蔽算法规则的场景;
网友评论