(转帖)小菜编程成长记(八 用“策略模式”是一种好策略)
来源:互联网 发布:苹果播放器哪个好 知乎 编辑:程序博客网 时间:2024/05/01 10:41
“你问我?你说呢?”大鸟笑道,“商场收银时如何促销,用打折还是返利,其实都是一些算法,用工厂来生成算法对象,感觉是不是很怪?而最重要的是这些算法是随时都可能互相替换的,这就是变化点,而封装变化点是我们面向对象的一种很重要的思维方式。”
这个模式涉及到三个角色:
- 环境(Context)角色:持有一个Strategy类的引用。
- 抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
- 具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。
“我明白了,”小菜说,“我昨天写的CashSuper就是抽象策略,而正常收费CashNormal、打折收费CashRebate和返利收费CashReturn就是三个具体策略,也就是策略模式中说的具体算法,对吧?”
“是的,那么关键就在于Context以及客户端程序如何写了?去查查资料,研究后把代码写出来给我看。”大鸟鼓励道。
“好的,我一定很快写出来给你看!”小菜很兴奋。
过一小时后,小菜给出商场收银程序的第四份作业。
CashContext类代码如下:
//收费策略Context
class CashContext
{
//声明一个现金收费父类对象
private CashSuper cs;
//设置策略行为,参数为具体的现金收费子类(正常,打折或返利)
public void setBehavior(CashSuper csuper)
{
this.cs = csuper;
}
//得到现金促销计算结果(利用了多态机制,不同的策略行为导致不同的结果)
public double GetResult(double money)
{
return cs.acceptCash(money);
}
}
客户端主要代码如下:
double total = 0.0d;//用于总计
private void btnOk_Click(object sender, EventArgs e)
{
CashContext cc = new CashContext();
switch (cbxType.SelectedItem.ToString())
{
case "正常收费":
cc.setBehavior(new CashNormal());
break;
case "满300返100":
cc.setBehavior(new CashReturn("300","100"));
break;
case "打8折":
cc.setBehavior(new CashRebate("0.8"));
break;
}
double totalPrices = 0d;
totalPrices = cc.GetResult(Convert.ToDouble(txtPrice.Text) * Convert.ToDouble(txtNum.Text));
total = total + totalPrices;
lbxList.Items.Add("单价:" + txtPrice.Text + " 数量:" + txtNum.Text + " "+cbxType.SelectedItem+ " 合计:" + totalPrices.ToString());
lblResult.Text = total.ToString();
}
实现的界面同之前一样(可点击使用)
“大鸟,我用策略模式是实现了,但有些疑问,用了策略模式,则把分支判断又放回到客户端来了,这等于要改变需求算法时,还是要去更改客户端的程序呀?”
“问得好,如果不是因为前面有工厂的例子,再来通过你的思考写出的这个策略模式的程序,你就问不出这样的问题的。”大鸟很开心,继续讲道,“最初的策略模式是有缺点的,客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道所有的算法或行为的情况。”
“那还不如工厂模式好用,至少要增加促销或改进打折额度时,不用去大改界面,而现在,界面程序要承担的责任还是太大。没有体现你说的封装变化点的作用呀。”小菜疑问多多。
“就目前而言,的确是这样,这样的程序确实还是不够完善,要改的地方还很多。”大鸟说道,“不过正所谓病毒时间长了会有变种,杀毒软件本身也会随着病毒的变化而升级改良,如果我们对策略模式做一些改进,引入一些新的技术处理方式,就可以避免现在的这种耦合了。小菜,又有新的东西要学了,好好加油呀!”
“大鸟,谢谢你,,你总是让我带着问题去思考,而不是直接说答案,我觉得这样学习进步很快,也不觉得设计模式很难了。”
“,用不着这么客气,我只是觉得,没有人是天生就牛X的,有一些所谓的技术牛人总会在人面前说什么,‘你连这都不懂’,‘这还不简单了,你够笨的’等等说词。给人感觉他非常聪明,天生就会的样子,其实他在之前也不知走过多少弯路,犯过多少错,或许他之前也被更早的牛人羞辱过,所以再继续把羞辱传给后人。”大鸟有些激动。
小菜小心的说道:“大鸟,你是不是也曾经被人羞……”
“哈哈,马云曾说过,男人的胸怀是被冤枉撑大的!天天在这行当里混,阅人无数,被羞辱也是正常的事了。问题在于是不是头脑清醒,自己不能放弃呀。所以我希望能真正的帮助初学者成长,而不是去显示牛气充当狂人。小菜,记住,学习一定是一个自己感悟的过程,而程序员的感悟就是自己写程序做项目,通过实践再学习,最终升华为牛人。”
“嗯,我记住了,不过到底如何改良策略模式呢?”
大鸟微笑不语。
- (转帖)小菜编程成长记(八 用“策略模式”是一种好策略)
- 小菜编程成长记(八 用“策略模式”是一种好策略)
- 小菜编程成长记(八 用“策略模式”是一种好策略)
- 小菜编程成长记(七 用“策略模式”是一种好策略)
- 大话设计模式(八 用“策略模式”是一种好策略)
- 小菜编程成长记系列 (很好的设计模式)
- (转帖)小菜编程成长记(一 面试受挫——代码无错就是好?)
- (转帖)小菜编程成长记(五 体会简单工厂模式的美妙)
- 小菜编程成长记(七 工厂不好用了?)
- 小菜编程成长记(六 工厂不好用了?)
- 小菜编程成长记(六 工厂不好用了?)
- 小菜编程成长记(八 反射——程序员的快乐!)
- 小菜编程成长记(一 面试受挫——代码无错就是好?)
- 小菜编程成长记(一 面试受挫——代码无错就是好?)
- 小菜编程成长记(一 面试受挫——代码无错就是好?)
- 小菜编程成长记(十三 设计模式不能戏说!设计模式怎就不能戏说?)
- (转帖)小菜编程成长记(六 工厂不好用了?)
- 小菜编程成长记
- C#中的值类型及装箱
- 论芙蓉精神于网站发展
- 全面掌握SOA 认清SOA面临的挑战
- 获取MS SQL库数据字典的经典SQL语句
- 毕业有感
- (转帖)小菜编程成长记(八 用“策略模式”是一种好策略)
- C++中union的应用剖析
- C# Infralution Licensing System学习笔记(四)Compact Framework Application应用
- 调试
- 怎样在MDI程序里面切换不同的 视图?
- 初恋有感
- NaviLibrary 研究手记(1)--Navi 介绍
- 一个socket通信的讲解
- 2008年6月3日,晴