例子来源于《大话设计模式》第二章。
策略模式的作用:封装算法
在简单工厂模式中,客户端需要认识两个类,分别是工厂类和抽象方法类。而在策略模式里,客户端只需要认识一个类,就是context类。因此,策略模式比简单工厂模式对算法的封装更加彻底。在
在学习一个设计模式的时候,一定要理解它的UML图,这对设计模式的理解很重要。
strategy.h
1 #include<iostream> 2 using namespace std; 3 //抽象方法类---现金收费 4 class CashSuper 5 { 6 public: 7 virtual double acceptcash(double money)=0;//纯虚函数 8 }; 9 //具体方法类-普通方式 10 class CashNormal:public CashSuper 11 { 12 public: 13 double acceptcash(double money) 14 { 15 return money; 16 } 17 }; 18 //具体方法---打折 19 class CashRebate:public CashSuper 20 { 21 private: 22 double discount; 23 public: 24 CashRebate(double discount)//构造函数。构造函数可以有参数,但是不能有返回值,void类型都不行 25 //在初始化的时候,传入具体的策略对象 26 { 27 this->discount=discount; 28 } 29 double acceptcash(double money) 30 { 31 return money*discount; 32 } 33 }; 34 //具体方法--满减 35 //满减是针对总共的价格来讲的 36 class CashReturn:public CashSuper 37 { 38 private: 39 double moneycondition; 40 double moneyreturn; 41 public: 42 43 CashReturn(double moneycondition,double moneyreturn)//构造函数,这个必须写,可以参考cashcontext.h里对这个类的调用 44 //在cashcontext.h里对它的调用有两个参数 45 //因为后面要new一个对象,并且给对象赋初值,所以必须写带参数的构造函数来调用 46 { 47 this->moneycondition=moneycondition; 48 this->moneyreturn=moneyreturn; 49 } 50 double acceptcash(double money) 51 { 52 double result=money; 53 if(money>=moneycondition) 54 { 55 result=money-money/moneycondition*moneyreturn; 56 } 57 return result; 58 } 59 };
CashContext.h
1 #include "strategy.h" 2 //context类 3 class CashFactory 4 { 5 CashSuper *cas;//子对象 6 public: 7 8 CashFactory(int type):cas(NULL) 9 //构造函数,通过初始化列表初始化数据成员 10 //子对象的初始化方式 11 //参数不是一个具体的收费策略的对象,而是一个表示收费类型的数字 12 //为什么这里写的注释和别的地方不一样??? 13 { 14 switch(type) 15 { 16 case 1: 17 cas=new CashNormal(); 18 break; 19 case 2: 20 cas=new CashRebate(0.8);//打折方式 21 break; 22 case 3: 23 cas=new CashReturn(200,100);//满减 24 break; 25 default:; 26 } 27 } 28 ~CashFactory()//析构函数.没有参数,没有返回值,不能重载 29 //作用是释放使用完的指针内存空间 30 { 31 if(cas!=NULL) 32 { 33 delete cas; 34 cas=NULL; 35 } 36 } 37 double getresult(double money) 38 { 39 return cas->acceptcash(money); 40 } 41 };
main.cpp
1 #include"CashContext.h" 2 #include<iostream> 3 using namespace std; 4 int main() 5 { 6 double totalprice=0.0; 7 CashFactory *cash=NULL;//策略模式只需要建立context的对象 8 cash=new CashFactory(2);//给新建的对象初始化 9 totalprice=cash->getresult(300);//使用context的对象访问对应的算法,参考context函数 10 cout<<totalprice; 11 return 0; 12 }
构造函数:
有两种:
1.自己写出来,根据自己要建立的对象初始化的方式来写自己需要的构造函数,可以有参数,也可以没参数,但是一旦写了没有参数的系统就不会提供默认的构造函数。
2.不写,系统会提供一个空的构造函数,里面什么都没有。但是这并不代表建立对象的时候不能将它初始化。
按照c++书上的说法,如果有参数,并且想要参数随着自己建立对象的不同而变化,就必须写自己的构造函数。但是也不一定。具体看下面我写的。
在c++中,建立一个对象,就必须调用构造函数。如果没有些构造函数,默认的构造函数不能对类中的成员初始化。但是,没有构造函数,公有的数据成员可以用初始值列表进行初始化。例如:
1 class Myclass 2 { 3 public: 4 int no; 5 int year; 6 }; 7 int main() 8 { 9 Myclass a={25,20}; 10 cout<<a.no<<endl; 11 cout<<a.year<<endl; 12 return 0; 13 }
但是对象的初始化如过写成
Myclass a(25,24);
就不行。
原因是这种初始化只能调用默认的构造函数,但是默认的构造函数没有参数。同理,如果new一个对象并初始化也不可以。