策略模式

 策略模式定义

策略模式(Strategy):它定义了算法家族,分别封装越来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。

策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,经可以相同的方式调用所有的算法,减少各种算法类与使用算法类之间的耦合。

策略模式实例

策略模式实例类图

 图 01 策略模式实例类图
策略模式的优点是简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试,好比你可以测试CCashRebate这个类。
策略模式就是用来封装算法的,但在实践中,我们发现用它来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用生吃模式处理这种变化的可能性。好比,一个商场要添加一个积累积分的功能,你只要编写一个实现积累积分的类,然后在context中进行添加相应代码即可。

策略模式实例代码

  1 #include "stdio.h"
  2 #include <Math.h>
  3 
  4 class CCashSuper
  5 {
  6 public:
  7     virtual double AcceptCash(double money) = 0;
  8     // 虚析构函数,指向子类的指针在delete时会调用子类的析构函数
  9     virtual ~CCashSuper()
 10     {
 11     
 12     }
 13 };
 14 
 15 // 无优惠
 16 class CCashNormal : public CCashSuper
 17 {
 18 public:
 19     virtual double AcceptCash(double money)
 20     {
 21         return money;
 22     }
 23     virtual ~CCashNormal()
 24     {
 25     
 26     }
 27 };
 28 
 29 // 打折
 30 class CCashRebate : public CCashSuper
 31 {
 32 private:
 33     double moneyRebate;
 34 public:
 35     CCashRebate(double moneyRebate)
 36     {
 37         this->moneyRebate = moneyRebate;
 38     }
 39 
 40     virtual double AcceptCash(double money)
 41     {
 42         return money * moneyRebate;
 43     }
 44     virtual ~CCashRebate()
 45     {
 46     
 47     }
 48 };
 49 
 50 // 满返
 51 class CCashReturn : public CCashSuper
 52 {
 53 private:
 54     double moneyCondition;
 55     double moneyReturn;
 56 public:
 57     CCashReturn(double moneyCondition, double moneyReturn)
 58     {
 59         this->moneyCondition = moneyCondition;
 60         this->moneyReturn = moneyReturn;
 61     }
 62 
 63     virtual double AcceptCash(double money)
 64     {
 65         if(money >= this->moneyCondition)
 66         {
 67             // 向下取整,要导入头文件<Math.h>
 68             money = money - floor(money / moneyCondition) * moneyReturn;
 69         }
 70         return money;
 71     }
 72     virtual ~CCashReturn()
 73     {
 74     
 75     }
 76 };
 77 
 78 // 上下文类(策略模式的核心)
 79 class CContext
 80 {
 81 private:
 82     CCashSuper *cs;
 83     double money;
 84 public:
 85     CContext(CCashSuper * cs)
 86     {
 87         this->cs = cs;
 88     }
 89 
 90     double GetResult(double money)
 91     {
 92         return this->cs->AcceptCash(money);
 93     }
 94 };
 95 
 96 void main()
 97 {
 98     CCashSuper *cs = NULL;
 99     CContext *ct;
100     double money = 0.0;
101     int number = 0;
102     double result = 0.0;        
103     printf("------------------------------\n\r");
104     printf("    1.无优惠\n\r");
105     printf("    2.打八折\n\r");
106     printf("    3.满300返100\n\r");
107     printf("------------------------------\n\r");
108     printf("请选择编号:");
109     // 获得编号1、2或3
110     char ch = getchar();
111     // 吸收回车键,可以不写
112     getchar();
113     switch(ch)
114     {
115     case '1':
116         cs = new CCashNormal();
117         break;
118     case '2':
119         cs = new CCashRebate(0.8);
120         break;
121     case '3':
122         cs = new CCashReturn(300, 100);
123         break;
124     default:
125         break;
126     }
127     printf("input money and number!\n");
128     printf("单价:");
129     // double 输入必须使用"%lf",要不然money中的数据将是你不认识的
130     scanf("%lf",&money);
131     // 吸收回车键,可以不写
132     getchar();
133     printf("数量:");
134     scanf("%d", &number);
135     // 吸收回车键,在这里这条指令是不能去除的,会导致意外事件,你可以试试
136     getchar();
137     printf("\n");
138     ct = new CContext(cs);
139     result = ct->GetResult(money * number);
140     // double 输出必须使用"%lf",要不然输出的数据将是你不认识的
141     printf("价格 = %.2lf\n", result);
142 
143     // 内存一定要释放
144     if(cs != NULL)
145     {
146         delete cs;
147         // 防止形成野指针
148         cs = NULL;
149     }
150     if(ct != NULL)
151     {
152         delete ct;
153         ct = NULL;
154     }
155 }

 策略模式与简单工厂模式非常的相像,唯一的区别在于CContext(上下文类)与COperationFactory(工厂类)有些区别,策略模式应用于需求经常变动,即需要经常添加新的功能,就是新的类,好比商场收费系统;简单工厂模式应用于类比较固定好比计算器的运算。二者可以结合,从而达到更好的效果。

 策略模式与简单工厂模式的结合代码

  1 #include "iostream"
  2 using namespace std;
  3 #include <Math.h>
  4 
  5 class CCashSuper
  6 {
  7 public:
  8     virtual double AcceptCash(double money) = 0;
  9     // 虚析构函数,指向子类的指针在delete时会调用子类的析构函数
 10     virtual ~CCashSuper()
 11     {
 12     
 13     }
 14 };
 15 
 16 // 无优惠
 17 class CCashNormal : public CCashSuper
 18 {
 19 public:
 20     virtual double AcceptCash(double money)
 21     {
 22         return money;
 23     }
 24     virtual ~CCashNormal()
 25     {
 26     
 27     }
 28 };
 29 
 30 // 打折
 31 class CCashRebate : public CCashSuper
 32 {
 33 private:
 34     double moneyRebate;
 35 public:
 36     CCashRebate(double moneyRebate)
 37     {
 38         this->moneyRebate = moneyRebate;
 39     }
 40 
 41     virtual double AcceptCash(double money)
 42     {
 43         return money * moneyRebate;
 44     }
 45     virtual ~CCashRebate()
 46     {
 47     
 48     }
 49 };
 50 
 51 // 满返
 52 class CCashReturn : public CCashSuper
 53 {
 54 private:
 55     double moneyCondition;
 56     double moneyReturn;
 57 public:
 58     CCashReturn(double moneyCondition, double moneyReturn)
 59     {
 60         this->moneyCondition = moneyCondition;
 61         this->moneyReturn = moneyReturn;
 62     }
 63 
 64     virtual double AcceptCash(double money)
 65     {
 66         if(money >= this->moneyCondition)
 67         {
 68             // 向下取整,要导入头文件<Math.h>
 69             money = money - floor(money / moneyCondition) * moneyReturn;
 70         }
 71         return money;
 72     }
 73     virtual ~CCashReturn()
 74     {
 75     
 76     }
 77 };
 78 
 79 // 上下文类(策略模式的核心) 策略模式与简单工厂模式的结合
 80 class CContext
 81 {
 82 private:
 83     CCashSuper *cs;
 84     double money;
 85 public:
 86     CContext(char ch)
 87     {
 88         switch(ch)
 89         {
 90         case '1':
 91             cs = new CCashNormal();
 92             break;
 93         case '2':
 94             cs = new CCashRebate(0.8);
 95             break;
 96         case '3':
 97             cs = new CCashReturn(300, 100);
 98             break;
 99         default:
100             break;
101         }
102     }
103 
104     double GetResult(double money)
105     {
106         return this->cs->AcceptCash(money);
107     }
108 
109     ~CContext()
110     {
111         // 内存一定要释放
112         if(cs != NULL)
113         {
114             delete cs;
115             cs = NULL;
116         }
117     }
118 };
119 
120 void main()
121 {
122     CContext *ct;
123     double money = 0.0;
124     int number = 0;
125     double result = 0.0;        
126     cout << "------------------------------\n\r";
127     cout << "    1.无优惠\n\r";
128     cout << "    2.打八折\n\r";
129     cout << "    3.满300返100\n\r";
130     cout << "------------------------------\n\r";
131     cout << "请选择编号:";
132     // 获得编号1、2或3
133     char ch = getchar();
134     // 吸收回车键,可以不写
135     getchar();
136     ct = new CContext(ch);
137     cout << "input money and number!" << endl;
138     cout << "单价:";
139     cin >> money;
140     // 吸收回车键,可以不写
141     getchar();
142     cout<< "数量:";
143     cin >> number;
144     ch = getchar();
145     result = ct->GetResult(money * number);
146     cout << "价格 = " << result << endl;
147     // 内存一定要释放
148     if(ct != NULL)
149     {
150         delete ct;
151         // 防止形成野指针
152         ct = NULL;
153     }
154 }

 

2014-11-26   23:07:31

posted on 2014-11-23 11:22  xiaoheike  阅读(1636)  评论(0)    收藏  举报

导航