现在的位置: 首页 > 综合 > 正文

简单工厂模式

2013年05月04日 ⁄ 综合 ⁄ 共 6238字 ⁄ 字号 评论关闭

原文:http://blog.csdn.net/tianshuai11/article/details/7671097#comments

一,概念

        从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫做静态工厂方法(StaticFactory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。 


二,菜鸟实现

  1. #include <iostream>  
  2. #include <exception>  
  3.   
  4. using namespace std;  
  5.   
  6. int main()  
  7. {  
  8.     try{  
  9.           
  10.         string a,b;  
  11.         char op;  
  12.         int result;   
  13.         cout<<"请输入数字A"<<endl;  
  14.         cin>>a;  
  15.         cout<<"请输入运算符(+,-,*,/)"<<endl;  
  16.         cin>>op;  
  17.         cout<<"请输入数字B"<<endl;  
  18.         cin>>b;  
  19.         int A=atoi(a.c_str());  
  20.         int B=atoi(b.c_str());  
  21.           
  22.         switch(op)  
  23.         {  
  24.             case '+':result=A+B;break;  
  25.             case '-':result=A-B;break;  
  26.             case '*':result=A*B;break;  
  27.             case '/':  
  28.                    if(B==0)  
  29.                       result=-9999;  
  30.                    else   
  31.                       result=A/B;  
  32.                       break;   
  33.             default:result =-9999;  
  34.         }     
  35.           
  36.         cout<<"result="<<result<<endl;  
  37.     }  
  38.     catch(exception &e)  
  39.     {  
  40.         cout<<"Exception:"<<e.what()<<endl;     
  41.     }  
  42.       
  43.     return 0;  
  44. }  

分析:程序实现还算可以,注意到了: 1)除数为0的判断,和异常的检查

                                                                     2)switch的应用,在C/C++中switch之接受 char 和 int 类型。其他的类型只能用if


存在的问题: 1)首先没有按照面向对象的设计方式实现。

                         2)不容易维护

                         3)不容易复用:控制台改成图形界面?只能复制代码,然后更改代码。不能直接调用代码类

                         4)不容易扩展:如果要添加 sqrt( ) 开方?如何实现?

                         5)灵活性不好:操作类和界面类没有分开。

解决办法:通过面向对象的三大技术封装、继承和多态


首先应用封装,让业务逻辑、界面逻辑分开,降低耦合度。

菜鸟进阶一:

  1. #include <iostream>  
  2. #include <exception>  
  3.   
  4. using namespace std;  
  5. class Operation  
  6. {  
  7. public:  
  8.  static int GetResult(int A,int B,char op) //static 静态类,所有对象共享一个方法   
  9. {  
  10.     int result;  
  11.     switch(op)  
  12.         {  
  13.             case '+':result=A+B;break;  
  14.             case '-':result=A-B;break;  
  15.             case '*':result=A*B;break;  
  16.             case '/':  
  17.                    if(B==0)  
  18.                       result=-9999;  
  19.                    else   
  20.                       result=A/B;  
  21.                       break;   
  22.             default:result =-9999;  
  23.         }     
  24.           
  25.     return result;  
  26. }  
  27.       
  28. } ;  
  29.   
  30. int main()  
  31. {  
  32.     Operation  operation;  
  33.     try{  
  34.           
  35.         string a,b;  
  36.         char op;  
  37.         int result;   
  38.         cout<<"请输入数字A"<<endl;  
  39.         cin>>a;  
  40.         cout<<"请输入运算符(+,-,*,/)"<<endl;  
  41.         cin>>op;  
  42.         cout<<"请输入数字B"<<endl;  
  43.         cin>>b;  
  44.         int A=atoi(a.c_str());  
  45.         int B=atoi(b.c_str());  
  46.           
  47.         result = operation.GetResult(A,B,op);  
  48.           
  49.         cout<<"result="<<result<<endl;  
  50.     }  
  51.     catch(exception &e)  
  52.     {  
  53.         cout<<"Exception:"<<e.what()<<endl;     
  54.     }  
  55.       
  56.     return 0;  
  57. }  

试想,如果想增加一个sqrt()。是不是还是要阅读源代码,然后在相应位置添加实现sqrt()的源代码,才可以实现。

如何才能实现松耦合呢?

采用面向对象技术的继承就可以。

菜鸟进阶二


  1. #include <iostream>  
  2. #include <exception>  
  3.   
  4. using namespace std;  
  5.   
  6. class Operation //操作运算基类   
  7. {  
  8. public:  
  9.     Operation(){}  
  10.     ~Operation(){}  
  11. public:  
  12.     double numberA;  
  13.     double numberB;  
  14.     char operate ;  
  15. public:  
  16.     void setNumberA(double number)//设置第一个操作数   
  17.     {  
  18.         numberA = number;  
  19.     }  
  20.     double getNumberA() //获取第一个操作数   
  21.     {  
  22.         return numberA;  
  23.     }  
  24.   
  25.     void setNumberB(double number)  
  26.     {  
  27.         numberB = number;  
  28.     }  
  29.     double getNumberB()  
  30.     {  
  31.         return numberB;  
  32.     }  
  33.   
  34. public:  
  35.     virtual double GetResult() //虚拟类   
  36.     {  
  37.         double result = 0;  
  38.         return result;  
  39.     }  
  40. };  
  41.   
  42.   
  43. class OperationAdd :public Operation  
  44. {  
  45. public:  
  46.     OperationAdd(void){}  
  47.     ~OperationAdd(void){}  
  48. public:  
  49.     double GetResult()  //重载基类中方法,实现加法   
  50.     {  
  51.         double result = 0;  
  52.         result = numberA + numberB;  
  53.         return result;  
  54.     }  
  55. };  
  56.   
  57. class OperationSub :public Operation  
  58. {  
  59. public:  
  60.     OperationSub(void){}  
  61.   
  62.     ~OperationSub(void){}  
  63. public:  
  64.     double GetResult()//重载基类中方法,实现减法   
  65.     {  
  66.         double result = 0;  
  67.         result =numberA - numberB;  
  68.         return result;  
  69.     }  
  70.   
  71. };  
  72.   
  73. class OperationMul :public Operation  
  74. {  
  75. public:  
  76.     OperationMul(void){}  
  77.     ~OperationMul(void){}  
  78. public:  
  79.     double GetResult()//重载基类中方法,实现乘法   
  80.     {  
  81.         double result = 0;  
  82.         result =numberA * numberB;  
  83.         return result;  
  84.     }  
  85. };  
  86.   
  87.   
  88. class OperationDiv :public Operation  
  89. {  
  90. public:  
  91.     OperationDiv(void){}  
  92.   
  93.     ~OperationDiv(void){}  
  94. public:  
  95.     double GetResult()//重载基类中方法,实现除法   
  96.     {  
  97.         double result = 0;  
  98.         result =numberA / numberB;  
  99.         return result;  
  100.     }  
  101. };  
  102.   
  103. class OperationFactory//运算工厂类   
  104. {  
  105. public:  
  106.     OperationFactory(){}  
  107.     ~OperationFactory(){}  
  108. public:  
  109.     Operation *oper; //运算基类 可以生成不同运算的子类(+,-,*,/)   
  110. public :  
  111.     Operation *createOperate(char operate) //返回类型是指针   
  112.     {  
  113.         switch (operate)  
  114.         {  
  115.         case '+':  
  116.             {  
  117.                 oper = new OperationAdd();  
  118.                 break;  
  119.             }  
  120.         case '-':  
  121.             {  
  122.                 oper = new OperationSub();  
  123.                 break;  
  124.             }  
  125.         case '*':  
  126.             {  
  127.                 oper = new OperationMul();  
  128.                 break;  
  129.             }  
  130.         case '/':  
  131.             {  
  132.                 oper = new OperationDiv();  
  133.                 break;  
  134.             }  
  135.         }  
  136.   
  137.         return oper;  
  138.     }  
  139. };  
  140.   
  141. int main()  
  142. {  
  143.     double strNumberA,strNumberB, result;  
  144.     char  strOperation;  
  145.     Operation *oper;  
  146.     OperationFactory factory;  
  147.     oper = factory.createOperate('*');  
  148.     oper->setNumberA(2);  
  149.     oper->setNumberB(4);  
  150.     result = oper->GetResult(); //调用的运算工厂返回的,各个操作运算符生成的对象  
  151.       
  152.     cout<<"result="<<result<<endl;   
  153.     return 0;  
  154. }  

整个程序结构说明:

class Operation                                       //操作运算基类 ,包含运算所必须的操作运算符和操作数,提供设定操作数和返回操作数方法

class OperationAdd :public Operation  //加法运算子类,设定运算结果

class OperationSub :public Operation  //减法运算子类

class OperationMul :public Operation  //乘法运算子类

class OperationDiv :public Operation  //除法运算子类

class OperationFactory                         //运算工厂类 ,负责生成各个操作运算符的类。


【注意】Operation *createOperate(char operate) //返回类型是指针


主要构成结构为: 操作运算符基类:定义操作必须的运算符和操作数,提供设定操作数和返回操作数方法

                                 四种运算子类:继承操作运算符基类,并实现每种运算符下的结果

                                 运算工厂:根据传递参数,生成不同运算符子类返回相应结果

                                 客户端:建立操作符基类,根据工厂生成子类,然后返回结果。

抱歉!评论已关闭.