有的书上把工厂模式分为三种:简单工厂、工厂方法和抽象工厂。GOF并没有把简单工厂作为设计模式之一列出。个人觉得简单工厂是工厂方法的一个特例。
一、简单工厂(Simple Factory)
作用:专门由一个类来决定实例化哪个产品类。
01 | #include <iostream> |
02 |
03 | using namespace std; |
04 |
05 | // 产品虚基类 |
06 | class Product |
07 | { |
08 | public : |
09 | virtual ~Product(){} |
10 |
11 | virtual void showProduct()=0; |
12 | }; |
13 |
14 | // 产品A |
15 | class ProductA: public Product |
16 | { |
17 | public : |
18 | virtual ~ProductA(){} |
19 | void showProduct() // 重写基类方法 |
20 | { |
21 | std::cout << "this is productA" << std::endl; |
22 | } |
23 | }; |
24 |
25 |
26 | // 产品B |
27 | class ProductB: public Product |
28 | { |
29 | public : |
30 | virtual ~ProductB(){} |
31 | void showProduct() // 重写基类方法 |
32 | { |
33 | std::cout << "this is productB" << std::endl; |
34 | } |
35 | }; |
36 |
37 | // 工厂类:我们用该类生成具体的产品 |
38 | class Factory |
39 | { |
40 | public : |
41 | Product *getProduct( int type) |
42 | { |
43 | if (0 == type) |
44 | { |
45 | return new ProductA; |
46 | } |
47 | else if (1 == type) |
48 | { |
49 | return new ProductB; |
50 | } |
51 | else |
52 | { |
53 | std::cout << "sorry i can't create this product" << std::endl; |
54 | return NULL; |
55 | } |
56 | } |
57 | }; |
58 |
59 | int main() |
60 | { |
61 | Factory* factory = new Factory(); |
62 | Product* product1 = factory->getProduct(0); |
63 | Product* product2 = factory->getProduct(1); |
64 | product1->showProduct(); |
65 | product2->showProduct(); |
66 |
67 | return 0; |
68 | } |
二、工厂方法(Factory Method)
上面提到的简单工厂是由一个类来完成创建产品的工作,我们想要得到某个产品时,需要传递给工厂类一个标识(type),工厂类根据type类型来生成不同的产品。工厂方法在此基础上有所变化,工厂类不想自己做这个工作了,它把自己提升为基类,具体的创建工作交给子类去完成,一般的每个子类只生产一个产品。
01 | #include <iostream> |
02 |
03 | using namespace std; |
04 |
05 | // 产品虚基类 |
06 | class Product |
07 | { |
08 | public : |
09 | virtual ~Product(){} |
10 |
11 | virtual void showProduct()=0; |
12 | }; |
13 |
14 | // 产品A |
15 | class ProductA: public Product |
16 | { |
17 | public : |
18 | virtual ~ProductA(){} |
19 | void showProduct() // 重写基类方法 |
20 | { |
21 | std::cout << "this is productA" << std::endl; |
22 | } |
23 | }; |
24 |
25 |
26 | // 产品B |
27 | class ProductB: public Product |
28 | { |
29 | public : |
30 | virtual ~ProductB(){} |
31 | void showProduct() // 重写基类方法 |
32 | { |
33 | std::cout << "this is productB" << std::endl; |
34 | } |
35 | }; |
36 |
37 | // 工厂类 |
38 | class Factory |
39 | { |
40 | public : |
41 | virtual ~Factory() {} |
42 | virtual Product *getProduct() = 0; |
43 | }; |
44 |
45 |
46 | // 工厂类A:只生产产品A |
47 | class FactoryA: public Factory |
48 | { |
49 | public : |
50 | virtual ~FactoryA(){} |
51 | Product *getProduct() |
52 | { |
53 | return new ProductA; |
54 | } |
55 | }; |
56 |
57 | // 工厂类B:只生产产品B |
58 | class FactoryB: public Factory |
59 | { |
60 | public : |
61 | virtual ~FactoryB(){} |
62 | Product *getProduct() |
63 | { |
64 | return new ProductB; |
65 | } |
66 | }; |
67 |
68 | int main() |
69 | { |
70 | Factory* factory1 = new FactoryA(); |
71 | Factory* factory2 = new FactoryB(); |
72 |
73 | Product* product1 = factory1->getProduct(); |
74 | Product* product2 = factory2->getProduct(); |
75 |
76 | product1->showProduct(); |
77 | product2->showProduct(); |
78 |
79 | delete product1; |
80 | delete product2; |
81 | delete factory1; |
82 | delete factory2; |
83 |
84 | return 0; |
85 | } |
三、抽象工厂(Abstract Factory)
上面提到的工厂方法,如果把产品定为汉堡、薯条和可乐,工厂类比成餐厅,用户可能会说给我一个汉堡,一个薯条和一杯可乐,发出三个命令来得到一顿饭。抽象工厂模式可以让用户只发出一个命令即可完成。
这里还是用网上一个例子说明:
001 | #include <iostream> |
002 |
003 | using namespace std; |
004 |
005 | // 产品虚基类 |
006 | class Product |
007 | { |
008 | public : |
009 | virtual ~Product(){} |
010 |
011 | virtual void showProduct()=0; |
012 | }; |
013 |
014 | // 产品:床 |
015 | class ProductBed: public Product |
016 | { |
017 | public : |
018 | virtual ~ProductBed(){} |
019 | void showProduct() // 重写基类方法 |
020 | { |
021 | std::cout << "this is ProductBed" << std::endl; |
022 | } |
023 | }; |
024 |
025 | // 产品:桌子 |
026 | class ProductDesk: public Product |
027 | { |
028 | public : |
029 | virtual ~ProductDesk(){} |
030 | void showProduct() // 重写基类方法 |
031 | { |
032 | std::cout << "this is ProductDesk" << std::endl; |
033 | } |
034 | }; |
035 |
036 | // 产品:门 |
037 | class ProductDoor: public Product |
038 | { |
039 | public : |
040 | virtual ~ProductDoor(){} |
041 | void showProduct() // 重写基类方法 |
042 | { |
043 | std::cout << "this is ProductDoor" << std::endl; |
044 | } |
045 | }; |
046 |
047 | // 产品:沙发 |
048 | class ProductSofa: public Product |
049 | { |
050 | public : |
051 | virtual ~ProductSofa(){} |
052 | void showProduct() // 重写基类方法 |
053 | { |
054 | std::cout << "this is ProductSofa" << std::endl; |
055 | } |
056 | }; |
057 |
058 | // 工厂类 |
059 | class Home |
060 | { |
061 | public : |
062 | virtual ~Home() {} |
063 | virtual void showMyHouse() = 0; |
064 | protected : |
065 | Product *bed; |
066 | Product *desk; |
067 | Product *door; |
068 | Product *sofa; |
069 |
070 | }; |
071 |
072 |
073 | // 工厂子类:只生产简单的家,包括床和门 |
074 | class SimpleHome: public Home |
075 | { |
076 | public : |
077 | SimpleHome() |
078 | { |
079 | bed = new ProductBed(); |
080 | door = new ProductDoor(); |
081 | } |
082 | virtual ~SimpleHome(){} |
083 | void showMyHouse() |
084 | { |
085 | bed->showProduct(); |
086 | door->showProduct(); |
087 | } |
088 | }; |
089 |
090 | // 工厂子类:生产高级的家,包括床、门、桌子和沙发 |
091 | class AdvancedHome: public Home |
092 | { |
093 | public : |
094 | AdvancedHome() |
095 | { |
096 | bed = new ProductBed(); |
097 | door = new ProductDoor(); |
098 | desk = new ProductDesk(); |
099 | sofa = new ProductSofa(); |
100 | } |
101 | virtual ~AdvancedHome(){} |
102 | void showMyHouse() |
103 | { |
104 | bed->showProduct(); |
105 | door->showProduct(); |
106 | desk->showProduct(); |
107 | sofa->showProduct(); |
108 | } |
109 | }; |
110 |
111 | // 调用工厂的客户类 |
112 | class Client |
113 | { |
114 | public : |
115 | Client(Home * newHome) |
116 | { |
117 | myHome = newHome; |
118 | } |
119 |
120 | void showHome() |
121 | { |
122 | myHome->showMyHouse(); |
123 | } |
124 | private : |
125 | Home *myHome; |
126 | }; |
127 |
128 |
129 | int main() |
130 | { |
131 | // 一个客户只想要一个简单的家 |
132 | Client *A = new Client( new SimpleHome); |
133 | A->showHome(); |
134 |
135 | // 另一个客户想要一个高级点的家 |
136 | Client *B = new Client( new AdvancedHome); |
137 | B->showHome(); |
138 |
139 | return 0; |
140 | } |