策略模式

来源:互联网 发布:淘宝客服处理技巧 编辑:程序博客网 时间:2024/06/11 19:51
策略模式

一,概念

        策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

二,策略模式的组成

   1)抽象策略角色: 策略类,通常由一个接口或者抽象类实现。
   2)具体策略角色:包装了相关的算法和行为。

   3)环境角色:持有一个策略类的引用,最终给客户端调用。

三,补充C++知识

类对象的构造顺序是这样的:
  1.分配内存,调用构造函数时,隐式/显示的初始化各数据成员
  2.进入构造函数后在构造函数中执行一般计算
       1)类里面的任何成员变量在定义时是不能初始化的。
       2)一般的数据成员可以在构造函数中初始化。
       3)const数据成员必须在构造函数的初始化列表中初始化。
       4)static要在类的定义外面初始化。   
       5)数组成员是不能在初始化列表里初始化的。
       6)不能给数组指定明显的初始化。  
这6条一起,说明了一个问题:C++里面是不能定义常量数组的!因为3和5的矛盾。这个事情似乎说不过去啊?没有办法,我只好转而求助于静态数据成员。
到此,我的问题解决。但是我还想趁机复习一下C++类的初始化:
  1.初始化列表:CSomeClass::CSomeClass() : x(0), y(1){}
  2.类外初始化:int CSomeClass::myVar=3;
  3.const常量定义必须初始化,C++类里面使用初始化列表;
  4.C++类不能定义常量数组。

在C++类中,必须做如下事情:

1.必须对任何const或引用类型成员以及没有默认构造函数的 类 类型 的任何成员 显示地使用初始化列表进行初始化

2.类成员在定义时是不能被初始化的

3.类的成员初始化顺序与成员变量在构造函数中的位置选后顺序无关,至于成员变量在类中定义的先后顺序有关

C++默认继承方式为private

C++ new 生成的对象为指针,所以new 前面的对象要声明为指针类型

四,实例

        计算器简单工厂模式的精简实现

[html] view plaincopy
  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4. class COperation//基类  
  5. {  
  6. public:  
  7.     int m_nFirst;  
  8.     int m_nSecond;  
  9.     virtual double GetResult()  
  10.     {  
  11.         double dResult=0;  
  12.         return dResult;  
  13.     }  
  14. };  
  15.   
  16. class AddOperation : public COperation//加法  
  17. {  
  18. public:  
  19.     virtual double GetResult()  
  20.     {  
  21.         return m_nFirst+m_nSecond;  
  22.     }  
  23. };  
  24.   
  25. class SubOperation : public COperation//减法  
  26. {  
  27. public:  
  28.     virtual double GetResult()  
  29.     {  
  30.         return m_nFirst-m_nSecond;  
  31.     }  
  32. };  
  33.   
  34.   
  35. class CCalculatorFactory//工厂类  
  36. {  
  37.       
  38. public://静态方法属于类本身,不属于哪个对象   
  39.     static COperation* Create(char cOperator);  
  40.   
  41. };  
  42.   
  43. COperation* CCalculatorFactory::Create(char cOperator)//工厂类的实现  
  44. {  
  45.     COperation *oper;  
  46.       
  47.     //在C#中可以用反射来取消判断时用的switch,在C++中用什么呢?RTTI??  
  48.     switch (cOperator)  
  49.     {  
  50.         case '+':  
  51.             oper=new AddOperation();  
  52.              break;  
  53.         case '-':  
  54.             oper=new SubOperation();  
  55.             break;  
  56.         default:  
  57.             oper=new AddOperation();  
  58.             break;  
  59.     }  
  60.     return oper;  
  61. }  
  62.   
  63. int main()  
  64. {  
  65.     int a,b;  
  66.     cin>>a>>b;  
  67.       
  68.     /*静态方法为类所有,可以通过对象来使用,也可以通过类来使用。  
  69.     但一般提倡通过类名来使用,因为静态方法只要定义了类,不必建立类的实例就可使用*/  
  70.     COperation * op = CCalculatorFactory::Create('-');//静态方法调用方式   
  71.     op->m_nFirst=a;  
  72.     op->m_nSecond=b;  
  73.     cout<<op->GetResult()<<endl;  
  74.     return 0;  
  75. }  

将简单工厂模式优化为策略模式后的代码如下:

[html] view plaincopy
  1. #include <iostream>  
  2. using namespace std;   
  3.   
  4. //策略基类  
  5. class COperation  
  6. {  
  7. public:  
  8.     int m_nFirst;  
  9.     int m_nSecond;  
  10.     virtual double GetResult()  
  11.     {  
  12.         double dResult=0;  
  13.         return dResult;  
  14.     }  
  15. };  
  16.   
  17. //策略具体类-加法类  
  18. class AddOperation : public COperation  
  19. {  
  20. public:  
  21.     AddOperation(int a,int b)  
  22.     {  
  23.         m_nFirst=a;  
  24.         m_nSecond=b;  
  25.     }  
  26.     virtual double GetResult()  
  27.     {  
  28.         return m_nFirst+m_nSecond;  
  29.     }  
  30. };  
  31.   
  32. class Context//策略类   
  33. {  
  34. private:  
  35.     COperation* op;  
  36. public:  
  37.     Context(COperation* temp)//参数为策略基类(传递的时候被初始化为子类)   
  38.     {  
  39.         op=temp;  
  40.     }  
  41.     double GetResult()  
  42.     {  
  43.         return op->GetResult();  
  44.     }  
  45. };  
  46.   
  47. //客户端  
  48. int main()  
  49. {  
  50.     int a,b;  
  51.     char c;  
  52.     cin>>a>>b;  
  53.     cout<<"请输入运算符:";  
  54.     cin>>c;  
  55.     switch(c)  
  56.     {  
  57.        case '+':  
  58.             Context *context=new Context(new AddOperation(a,b));  
  59.                 cout<<context->GetResult()<<endl;  
  60.             break;  
  61.        default:  
  62.             break;  
  63.     }  
  64.     return 0;  
  65. }  

这里将策略(操作符)封装成一个Context类,通过传递操作符子对象来返回相应子对象下操作结果。

实现工厂模式和策略模式

        客户端只需访问Context类,而不用知道其它任何类信息,实现了低耦合。在上例基础上,修改下面内容

[html] view plaincopy
  1. #include <iostream>  
  2. using namespace std;  
  3.    
  4.    
  5.  //策略基类  
  6. class COperation  
  7. {  
  8. public:  
  9.     int m_nFirst;  
  10.     int m_nSecond;  
  11.     virtual double GetResult()  
  12.     {  
  13.         double dResult=0;  
  14.         return dResult;  
  15.     }  
  16. };  
  17.   
  18. //策略具体类-加法类  
  19. class AddOperation : public COperation  
  20. {  
  21. public:  
  22.     AddOperation(int a,int b)  
  23.     {  
  24.         m_nFirst=a;  
  25.         m_nSecond=b;  
  26.     }  
  27.     AddOperation()  
  28.     {  
  29.         m_nFirst=0;  
  30.         m_nSecond=0;  
  31.     }  
  32.     virtual double GetResult()  
  33.     {  
  34.         return m_nFirst+m_nSecond;  
  35.     }  
  36. };  
  37. class Context  
  38. {  
  39. private:  
  40.     COperation* op;  
  41. public:  
  42.     Context(char cType)  
  43.     {  
  44.         switch (cType)  
  45.         {  
  46.         case '+':  
  47.             op=new AddOperation(3,8);  
  48.             break;  
  49.         default:  
  50.             op=new AddOperation();  
  51.             break;  
  52.         }  
  53.     }  
  54.     double GetResult()  
  55.     {  
  56.         return op->GetResult();  
  57.     }  
  58. };  
  59. //客户端  
  60. int main()  
  61. {  
  62.     Context *test=new Context('+');  
  63.     cout<<test->GetResult()<<endl;  
  64.     return 0;  
  65. }  
参考来源:http://blog.csdn.net/tianshuai11/article/details/7671823