简单工厂模式

大二上设计模式时,老师推荐了一本书叫大话设计模式,现在才入手看看,感觉例子确实蛮不错的。

第一种简单工厂模式,

书中给的例子是商城购物收银时,经常有优惠活动,有的是打折,有的是满多少返多少类似的情况等等。

开始大牛让菜鸡写个简单工厂,菜鸡的实现的第一种形式就是每给一种打折,写个工厂子类。

于是大牛表示这么写,子类可能太多,为什么不找找这些打优惠类的共同点。

“面向对象的编程,并不是类越多越好,类的划分是为了封装,但分类的基础是抽象”

于是菜鸡总结了下,发现其实归纳起来只有3个子类,

1是无优惠的原价收费

2是打几折的优惠

3是满多少返多少的优惠

参数有区别而已。

于是实现如下

 1 #include <iostream>
 2 using namespace std;
 3 class CashSuper
 4 {
 5 public:
 6     virtual float AcceptCash(float)=0;
 7 };
 8 
 9 class CashNormal:public CashSuper
10 {
11 public:
12     virtual float AcceptCash(float cash)
13     {
14         return cash;
15     }
16 };
17 
18 class CashRebate:public CashSuper
19 {
20 private:
21     float m_rebate;
22 public:
23     CashRebate(float r):m_rebate(r){}
24     virtual float AcceptCash(float cash)
25     {
26         return cash*m_rebate;
27     }
28 };
29 
30 class CashReturn:public CashSuper
31 {
32 private:
33     int m_condition;
34     int m_return;
35 public:
36     CashReturn(int c,int r):m_condition(c),m_return(r){}
37     virtual float AcceptCash(float cash)
38     {
39         return cash-(int)cash/m_condition*m_return;
40     }
41 };
42 class CashFactory
43 {
44 public:
45     enum CASHTYPE{NORMAL,REBATE,CASHRETURN};
46 public:
47     CashSuper* CreateCashAccept(CASHTYPE ct)
48     {
49         CashSuper* cs=NULL;
50         switch(ct)
51         {
52         case NORMAL:
53             cs=new CashNormal();
54             break;
55         case REBATE:
56             cs=new CashRebate(0.8f);
57             break;
58         case CASHRETURN:
59             cs=new CashReturn(300,100);
60             break;
61 
62         }
63         return cs;
64     }
65 };
66 
67 int main()
68 {
69     CashFactory cf;
70     CashSuper* cs=cf.CreateCashAccept(CashFactory::REBATE);
71     cout<<cs->AcceptCash(300);
72     return 0;
73 }

 写完后发现enum类型能根据的值来switch case...而且类里面定义的enum类型要在外部访问也得public:

比如可以

        case 0:
            cs=new CashNormal();
            break;
        case 1:
            cs=new CashRebate(0.8f);
            break;
        case CASHRETURN:
            cs=new CashReturn(300,100);
            break;

但是外部调用时,由于函数接收的参数是ENUM类型
不能直接
CashSuper* cs=cf.CreateCashAccept(1);
强制转换一下
CashSuper* cs=cf.CreateCashAccept((CashFactory::CASHTYPE)1);