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
10
using 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.
16
class NB
17

{
18
protected:
19
NB()
{} // NOT allow myself to instanced.
20
21
public:
22
23
};
24
25
class CommerceNB : public NB
26

{
27
public:
28
CommerceNB()
{
29
cout << "You bought a NoteBook face to commerce." << endl;
30
}
31
};
32
33
class EnterpriseNB : public NB
34

{
35
public:
36
EnterpriseNB()
{
37
cout << "You bought a NoteBook face to enterprise." << endl;
38
}
39
};
40
41
class MultimediaNB : public NB
42

{
43
public:
44
MultimediaNB()
{
45
cout << "You bought a NoteBook face to multimedia." << endl;
46
}
47
};
48
49
// define PC for product.
50
class PC
51

{
52
protected:
53
PC()
{} // NOT allow myself to instanced.
54
55
public:
56
57
};
58
59
class CommercePC : public PC
60

{
61
public:
62
CommercePC()
{
63
cout << "You bought a PC face to commerce." << endl;
64
}
65
};
66
67
class EnterprisePC : public PC
68

{
69
public:
70
EnterprisePC()
{
71
cout << "You bought a PC face to enterprise." << endl;
72
}
73
};
74
75
class MultimediaPC : public PC
76

{
77
public:
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.
86
class Founder
87

{
88
protected:
89
Founder()
{cout << "Founder: ";} // NOT allow myself to instanced.
90
91
public:
92
virtual NB* getNB() = 0;
93
virtual PC* getPC() = 0;
94
95
};
96
/**//*
97
NB* Founder::getNB()
98
{
99
}
100
101
PC* Founder::getPC()
102
{
103
}*/
104
105
// define commerce style for factory.
106
class CommerceFounder : public Founder
107

{
108
public:
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.
124
class EnterpriseFounder : public Founder
125

{
126
public:
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.
142
class MultimediaFounder : public Founder
143

{
144
public:
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
162
class Dept
163

{
164
protected:
165
Dept()
{cout << "Company: ";} // NOT allow myself to instanced.
166
Founder* _vendor;
167
168
public:
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
183
class DevDept : public Dept
184

{
185
public:
186
DevDept()
{
187
cout << "Development Dept. need to stocking enterprise product." << endl;
188
_vendor = new EnterpriseFounder();
189
}
190
191
};
192
193
class HrDept : public Dept
194

{
195
public:
196
HrDept()
{
197
cout << "HumanResource Dept. need to stocking commercial product." << endl;
198
_vendor = new CommerceFounder();
199
}
200
201
};
202
203
class AdDept : public Dept
204

{
205
public:
206
AdDept()
{
207
cout << "ArtDesign Dept. need to stocking entertainment product." << endl;
208
_vendor = new MultimediaFounder();
209
}
210
211
};
212
213
int 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.
232
int 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.