读书人

狂言设计模式之策略模式

发布时间: 2013-02-15 15:46:56 作者: rapoo

大话设计模式之策略模式

在做一件事情完成一项任务时,往往会有很多个方法,这每一种方法都可以被称为策略,我们会根据不同的环境或条件,从众多方法中选取一个合适的方法来完成这件事情或任务。就像我们过年回家,回家的方式有很多种,比如坐飞机、乘坐火车、坐客车、走路等等,但是由于自身条件限制或者环境限制,我们往往会选择一个比较适合自己的回家方式回家。而我们选用的这个方法就可以称之为策略。

其实所谓的策略模式,是一种对象行为型模式,它定义了算法家族,然后分别对算法封装,让算法之间可以相互替换。这个模式让算法的变化,不会影响到使用算法的客户。它也被称之为政策模式。

策略模式的结构图:

狂言设计模式之策略模式

Strategy类:

为Context定义了一系列的可以被重用的算法或者行为。

ConcreteStrategy类:

具体策略类,它封装了具体的算法或行为,继承Strategy类,有助于析取出这些算法中的公共功能。

策略模式应用举例:

代码结构图:

狂言设计模式之策略模式

窗体设计图:

狂言设计模式之策略模式

代码实现:

[csharp] view plaincopy
  1. double total = 0.0d;
  2. private void btnOK_Click(object sender, EventArgs e)
  3. {
  4. CashContext csuper = new CashContext(cmbType.SelectedItem.ToString());
  5. double totalPrices = 0d;
  6. totalPrices = csuper . GetResult (Convert.ToDouble(txtPrice.Text) * Convert.ToDouble(txtNum.Text));
  7. total = total + totalPrices;
  8. listBox1.Items.Add("单价:" + txtPrice.Text + "数量:" + txtNum.Text + "合计:" + totalPrices.ToString());
  9. lblTotal.Text =Convert .ToString ( total) ;
  10. }
  11. private void btnRef_Click(object sender, EventArgs e)
  12. {
  13. txtPrice.Text = "";
  14. txtNum.Text = "";
  15. listBox1.Text = "";
  16. lblTotal.Text = "";
  17. }
  18. private void Form1_Load(object sender, EventArgs e)
  19. {
  20. cmbType.Items .AddRange (new object []{"正常收费","打八折","打七折","打五折","满300返100"});
  21. cmbType.SelectedIndex = 0;
  22. }
  23. }
  24. class CashContext
  25. {
  26. CashSuper cs = null;
  27. public CashContext(string type)//string type不是具体的收费策略,而是一个字符串,表示收费类型
  28. {
  29. switch (type )
  30. {
  31. case "正常收费":
  32. CashNormal cs0 = new CashNormal();
  33. cs = cs0;
  34. break;
  35. case "满300返100":
  36. CashReturn cs1 = new CashReturn("300","100");
  37. cs = cs1;
  38. break;
  39. case "打八折":
  40. CashRebate cs2 = new CashRebate("0.8");
  41. cs = cs2;
  42. break;
  43. }
  44. }
  45. public double GetResult(double money)
  46. {
  47. return cs.acceptCash(money);
  48. }
  49. }
  50. abstract class CashSuper //现金收取的抽象类
  51. {
  52. public abstract double acceptCash(double money);
  53. }
  54. class CashNormal : CashSuper //子类之正常收费类
  55. {
  56. public override double acceptCash(double money)
  57. {
  58. return money;
  59. }
  60. }
  61. class CashRebate : CashSuper //打折收费类
  62. {
  63. private double moneyRebate = 1d;
  64. public CashRebate (string moneyRebate)
  65. {
  66. this.moneyRebate = double.Parse(moneyRebate);
  67. }
  68. public override double acceptCash(double money)
  69. {
  70. return money * moneyRebate;
  71. }
  72. }
  73. class CashReturn : CashSuper //满多少返回多少类
  74. {
  75. private double moneyCondition = 0.0d;
  76. private double moneyReturn = 0.0d;
  77. public CashReturn(string moneyCondition, string moneyReturn)
  78. {
  79. this.moneyCondition = double.Parse(moneyCondition);
  80. this.moneyReturn = double.Parse(moneyReturn);
  81. }
  82. public override double acceptCash(double money)
  83. {
  84. double result = money;
  85. if (money >= moneyCondition)
  86. result = money - moneyReturn;
  87. return result;
  88. }
  89. }

策略模式的适用:

第一:如果一个系统中有很多类,而他们的区别也只是在于他们的行为,这时就可以使用策略模式从众多行为中选取其中一种行为。

第二:一个系统需要动态的从多种算法中选取某一种算法。

第三:系统有复杂的、与算法相关的数据结构,而我们又不希望客户端的客户知道这些数据结构,在具体策略中封装算法和相关数据结构,以确保算法的安全性,对算法保密。

第四:当不同的行为堆放在一个类中,就难免在执行时,会使用条件语句来选择某一种合适的行为。

策略模式的优点:

第一:简化了单元测试,每个算法都有自己的类,可以通过自己的接口来单独测试。

第二:可以避免使用多重条件转移语句,使之易维护。

第三:策略模式定义了一系列算法行为,所有算法完成的都是相同工作,只是实现不同,它可以以相同方式调用所有算法,减少各种与使用算法类之间的耦合。

2楼jiben2qingshan昨天 21:12
Re: dandanzmc昨天 21:24
回复jiben2qingshann呵呵,why
Re: jiben2qingshan昨天 21:41
回复dandanzmcnno why
1楼cjr15233661143昨天 19:55
真仔细啊 ,小朱加油啊
Re: dandanzmc昨天 20:50
回复cjr15233661143n(*^__^*) 嘻嘻……小女子谢过夸奖

读书人网 >软件开发

热点推荐