策略模式
策略模式定义
策略模式(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
浙公网安备 33010602011771号