设计模式2:策略模式

例子来源于《大话设计模式》第二章。

策略模式的作用:封装算法

在简单工厂模式中,客户端需要认识两个类,分别是工厂类和抽象方法类。而在策略模式里,客户端只需要认识一个类,就是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一个对象并初始化也不可以。

 

posted @ 2019-08-13 16:03  妮妮熊  阅读(174)  评论(0编辑  收藏  举报