abstract factory:为创建相互关联(风格类似)的一系列的对象提供了一个通用接口,而不需要指定具体的类(产品)名。
factory method:定义一个用来创建对象的接口,并让子类来决定实例化哪一个具体的类(产品),从而让具体类的实例化延迟到子类。
他们的主要区别在于,abstract factory强调的是把诺干个产品按照风格进行分类, 为相同风格的一系列对象(产品)提供一个工厂类,因此,只要改变工厂类的实例,就能到达改变这一组产品的风格和外观。而这一风格的产品的生产可以利用工厂方法来实现. 这其中, factory method强调的则是先在父类实现创建对象的行为,具体的行为或者具体对象(产品)的实例化则延迟到子类实现。
例子说明:
对于笔记本和PC机可能分为,商务级(commerce),企业级(enterprise),多媒体级(multimedia)这几种类型。
一家公司的几个部门要采购一批机器,选择的制造商是方正(founder)。
另外,根据部门的不同,采购的机器的类型也不同,例如,开发部,因为侧重于软件开发,所以需要采购企业级的产品,包括笔记本和PC机;人力资源部的工作人员因为要经常出门,所以需要采购商务级的笔记本;美工部,则侧重于多媒体制作,所以需要多媒体级的PC机。
对于制造商方正来说,需要为相同类型的笔记本和PC机抽象出一个与该类型的对应的工厂类。那么,对于客户(采购电脑的公司)来说,方正是抽象工厂,笔记本和PC机是产品,所以这里决定采用抽象工厂模式。
对于公司这边来讲,并不知道各个部门需要哪一种类型的电脑,因为,什么样的电脑才合适,只有需要采购电脑的实际部门才真正了解。因此公司只提供采购电脑的方法,具体采购哪一种类型的电脑,延迟到实际部门再做决定。对于员工(客户)来说,公司是工厂(creator),方正是他的产品.所以,这里采用工厂方法比较合适。
1//factory.cpp
2
3
4
5
6// C++ Sample of Abstract Factory & Factory Method of Deisgn Pattern
7
8#include <iostream>
9
10using namespace std;
11
12// abstract factory is used by defining product.
13
14// assume product style to be Commerce, Enterprise, Multimedia.
15// define NoteBook for product.
16class NB
17{
18protected:
19 NB() {} // NOT allow myself to instanced.
20
21public:
22
23};
24
25class CommerceNB : public NB
26{
27public:
28 CommerceNB() {
29 cout << "You bought a NoteBook face to commerce." << endl;
30 }
31};
32
33class EnterpriseNB : public NB
34{
35public:
36 EnterpriseNB() {
37 cout << "You bought a NoteBook face to enterprise." << endl;
38 }
39};
40
41class MultimediaNB : public NB
42{
43public:
44 MultimediaNB() {
45 cout << "You bought a NoteBook face to multimedia." << endl;
46 }
47};
48
49// define PC for product.
50class PC
51{
52protected:
53 PC() {} // NOT allow myself to instanced.
54
55public:
56
57};
58
59class CommercePC : public PC
60{
61public:
62 CommercePC() {
63 cout << "You bought a PC face to commerce." << endl;
64 }
65};
66
67class EnterprisePC : public PC
68{
69public:
70 EnterprisePC() {
71 cout << "You bought a PC face to enterprise." << endl;
72 }
73};
74
75class MultimediaPC : public PC
76{
77public:
78 MultimediaPC() {
79 cout << "You bought a PC face to multimedia." << endl;
80 }
81};
82
83// according to style, define three factory.
84
85// define vendor Founder for abstract factory.
86class Founder
87{
88protected:
89 Founder() {cout << "Founder: ";} // NOT allow myself to instanced.
90
91public:
92 virtual NB* getNB() = 0;
93 virtual PC* getPC() = 0;
94
95};
96/**//*
97NB* Founder::getNB()
98{
99}
100
101PC* Founder::getPC()
102{
103}*/
104
105// define commerce style for factory.
106class CommerceFounder : public Founder
107{
108public:
109 NB* getNB() {
110 return new CommerceNB();
111 }
112
113 PC* getPC() {
114 return new CommercePC();
115 }
116
117 CommerceFounder() {
118 cout << "Welcom to select commercial product." << endl;
119 }
120
121};
122
123// define enterprise style for factory.
124class EnterpriseFounder : public Founder
125{
126public:
127 NB* getNB() {
128 return new EnterpriseNB();
129 }
130
131 PC* getPC() {
132 return new EnterprisePC();
133 }
134
135 EnterpriseFounder() {
136 cout << "Welcom to select enterprise product." << endl;
137 }
138
139};
140
141// define multimedia style for factory.
142class MultimediaFounder : public Founder
143{
144public:
145 NB* getNB() {
146 return new MultimediaNB();
147 }
148
149 PC* getPC() {
150 return new MultimediaPC();
151 }
152
153 MultimediaFounder() {
154 cout << "Welcom to select entertainment product." << endl;
155 }
156
157};
158
159#if 1
160// factory method is used by defining computer's stock.
161// defined Dept. of company
162class Dept
163{
164protected:
165 Dept() {cout << "Company: ";} // NOT allow myself to instanced.
166 Founder* _vendor;
167
168public:
169 virtual NB* buyNB() {
170 _vendor->getNB();
171 }
172
173 virtual PC* buyPC() {
174 _vendor->getPC();
175 }
176
177 virtual ~Dept() {
178 delete _vendor;
179 }
180
181};
182
183class DevDept : public Dept
184{
185public:
186 DevDept() {
187 cout << "Development Dept. need to stocking enterprise product." << endl;
188 _vendor = new EnterpriseFounder();
189 }
190
191};
192
193class HrDept : public Dept
194{
195public:
196 HrDept() {
197 cout << "HumanResource Dept. need to stocking commercial product." << endl;
198 _vendor = new CommerceFounder();
199 }
200
201};
202
203class AdDept : public Dept
204{
205public:
206 AdDept() {
207 cout << "ArtDesign Dept. need to stocking entertainment product." << endl;
208 _vendor = new MultimediaFounder();
209 }
210
211};
212
213int main(int agrc, char* argv[])
214{
215 Dept* dev = new DevDept();
216 Dept* hr = new HrDept();
217 Dept* ad = new AdDept();
218
219 delete dev->buyNB();
220 delete dev->buyPC();
221 delete hr->buyNB();
222 delete ad->buyPC();
223
224 delete dev;
225 delete hr;
226 delete ad;
227
228 return 0;
229}
230#else
231// only for test.
232int main(int argc, char* argv[])
233{
234 Founder* founder = new EnterpriseFounder();
235 founder->getNB();
236
237 return 0;
238}
239#endif
240
UML关系图如下
编译以及执行结果
lymons@d3-liutao ~
$ g++ factory.cpp -o factory
lymons@d3-liutao ~
$ ./factory.exe
Company: Development Dept. need to stocking enterprise product.
Founder: Welcom to select enterprise product.
Company: HumanResource Dept. need to stocking commercial product.
Founder: Welcom to select commercial product.
Company: ArtDesign Dept. need to stocking entertainment product.
Founder: Welcom to select entertainment product.
You bought a NoteBook face to enterprise.
You bought a PC face to enterprise.
You bought a NoteBook face to commerce.
You bought a PC face to multimedia.