设计模式的目的就是尽量减少“变化”对程序的影响,尤其是对客户程序的影响。AbstractFactory模式作为创建型模式的一种,解决的就是“new”在变化中可能引起的问题。
先来看看new有何种不好,举个创建汽车的车门的例子:
很自然的一种想法是:Door *door = new Door();
但是如果遇到创建老爷车的车门,创建现代车的车门,这段代码就无所适从了。
OO为我们提供了哪些精华的思想?“封装”,是的,将车门的创建封装起来,于是我们有了静态工厂方法:
客户程序代码:
1
Door
*
door
=
doorFactory
->
CreateDoor();
库程序代码:
1
class
DoorFactory
2
![](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
3
public:
4
Door* CreateDoor()
5![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
{
6
return new Door();
7
}
8
}
客户程序在此是不会变化的,不管你是老爷车门,现代车门,还是钻石车门,这些和客户程序代码都是没关系的,究竟CreateDoor出来如何结果都交给多态来判断,我们不用操心。
但是库程序代码还是需要更改的,但我们已经将“变化”与客户程序隔离了。
需求又有变化了,不光要创建车门,还需要创建引擎,车灯,而且还是不同风格的。
这时候静态工厂已经应付不来了,静态工厂有其自身的缺陷“不能应对不同系列对象”的变化。
动机:
软件系统中,经常面临“一系列相互依赖的对象”的创建工作。(两个特征:“一系列”,“相互依赖”)
将创建过程封装起来,避免“客户程序”和“多系列具体对象的创建工作”的紧耦合。
意图:
提供一个接口,让该接口负责创建一系列“相关或者相互依赖的对象”,无需指定他们具体的类。(GoF23)
思路:
![](https://i-blog.csdnimg.cn/blog_migrate/85606b66217805319b748a8f8d9f639d.jpeg)
对于客户程序来说,只依赖于三个抽象的类:AbstractFactory,AbstractProductA,AbstractProductB。
以下是客户程序代码:
1
class
CarManager
2
![](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
3
protected:
4
AbstractFactory *abstractFactory;
5
public:
6
//创造Car
7
void createCar(AbstractFactory *abstractFactory)
8![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
{
9
abstractFactory->CreateEngine();
10
abstractFactory->CreateDoor();
11
abstractFactory->CreateLight();
12
}
13
//其他的操作![](https://i-blog.csdnimg.cn/blog_migrate/918e8df969f9f8c8d002f25cda86cade.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/918e8df969f9f8c8d002f25cda86cade.gif)
14![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
void run()
{}
15
}
;
16
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
17
int
_tmain(
int
argc, _TCHAR
*
argv[])
18
![](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
19
CarManager *carManager = new CarManager();
20
//创建Classic风格的汽车
21
carManager->createCar(new ClassicFactory());
22![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
23
return 0;
24
}
所有关于创建的操作都是用抽象类完成的,对于具体是何种类型的对象由多态实现,以此来使“客户代码”和“多系列具体对象的创建工作”达到松耦合。
如果遇到还需要扩展其他风格的汽车,可以按下图的思路
![](https://i-blog.csdnimg.cn/blog_migrate/c6b6382da62042b29688264342c7db00.jpeg)
红色的部分对应新风格的车辆,只需在库程序中添加ConcreteFactory3,ProductA3,ProductB3三个类,而对于客户代码CarManager来说完全不受影响。
总结:
AbstractFactory模式有以下三个要点:
1.应对的问题是“多风格的系列对象创建”的变化问题,“系列对象”指的是这些对象之间有相互依赖或者相互作用的关系。否则使用“静态工厂”足以。
2.抽象工厂和静态工厂的核心是“封装”,将对象的创建进行封装,避免“new”引起的问题
3.抽象工程的另一个核心是“多态”,通过动态绑定来处理“不同风格”的问题
注:
AbstractFactory模式主要针对“风格”的变化,如果“对象”本身经常变化,那么该模式并不适用。
自己做的示例代码,仅供参考
1
/**/
//
2
//
AbstractFactoryTest for AbstractFactory Pattern Test
3
//
4
![](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
/**/
//
5
6
#include
"
stdafx.h
"
7
#include
"
iostream
"
8
using
namespace
std;
9
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
10
//
Engine,Door,Light are the Abstract Product
11
//
这三个类对应UML图中的AbstractProduct类
12
class
Engine
13
![](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
14
public:
15
Engine()
16![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
{
17
cout<<"Abstract Engine Create"<<endl;
18
}
19
virtual void doSomething() = 0;
20
}
;
21
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
22
class
Door
23
![](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
24
public:
25
Door()
26![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
{
27
cout<<"Abstract Door Create"<<endl;
28
}
29
virtual void doSomething() = 0;
30
}
;
31
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
32
class
Light
33
![](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
34
public:
35
Light()
36![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
{
37
cout<<"Abstract Light Create"<<endl;
38
}
39
virtual void doSomething() = 0;
40
}
;
41
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
42
//
Abstract Factory
43
class
AbstractFactory
44
![](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
45
public:
46
AbstractFactory()
47![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
{
48
cout<<"AbstractFactory Create"<<endl;
49
}
50
virtual Engine* CreateEngine() = 0;
51
virtual Door* CreateDoor() = 0;
52
virtual Light* CreateLight() = 0;
53
}
;
54
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
55
//
SpeedEngine,SpeedDoor,SpeedLight are the Products of Speed Style
56
//
这三个类对应UML图中的ProductA1,ProductB1,ProductC1类
57
class
SpeedEngine:
public
Engine
58
![](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
59
public :
60
SpeedEngine()
61![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
{
62
cout<<"Speed Engine Create"<<endl;
63
}
64![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
void doSomething()
{ }
65
}
;
66
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
67
class
SpeedDoor:
public
Door
68
![](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
69
public :
70
SpeedDoor()
71![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
{
72
cout<<"Speed Door Create"<<endl;
73
}
74![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
void doSomething()
{ }
75
}
;
76
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
77
class
SpeedLight:
public
Light
78
![](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
79
public :
80
SpeedLight()
81![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
{
82
cout<<"Speed Light Create"<<endl;
83
}
84![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
void doSomething()
{ }
85
}
;
86
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
87
//
classicEngine,classicDoor,classicLight are the products of Classic style
88
//
这三个类对应UML图中的ProductA2,ProductB2,ProductC2类
89
class
ClassicEngine:
public
Engine
90
![](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
91
public :
92
ClassicEngine()
93![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
{
94
cout<<"Classic Engine Create"<<endl;
95
}
96![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
void doSomething()
{ }
97
}
;
98
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
99
class
ClassicDoor:
public
Door
100
![](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
101
public :
102
ClassicDoor()
103![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
{
104
cout<<"Classic Door Create"<<endl;
105
}
106![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
void doSomething()
{ }
107
}
;
108
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
109
class
ClassicLight:
public
Light
110
![](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
111
public :
112
ClassicLight()
113![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
{
114
cout<<"Classic Light Create"<<endl;
115
}
116![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
void doSomething()
{ }
117
}
;
118
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
119
//
Factory for Speed Cars
120
//
对应UML图中的ConcreteFactory1类
121
class
SpeedFactory:
public
AbstractFactory
122
![](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
123
public:
124
SpeedFactory()
125![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
{
126
cout<<"SpeedFactory Create"<<endl;
127
}
128
virtual Engine* CreateEngine()
129![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
{
130
return new SpeedEngine();
131
}
132
virtual Door* CreateDoor()
133![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
{
134
return new SpeedDoor();
135
}
136
virtual Light* CreateLight()
137![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
{
138
return new SpeedLight();
139
}
140
}
;
141
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
142
//
Factory for classic Cars
143
//
对应UML图中的ConcreteFactory2类
144
class
ClassicFactory:
public
AbstractFactory
145
![](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
146
public:
147
ClassicFactory()
148![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
{
149
cout<<"ClassicFactory Create"<<endl;
150
}
151
virtual Engine* CreateEngine()
152![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
{
153
return new ClassicEngine();
154
}
155
virtual Door* CreateDoor()
156![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
{
157
return new ClassicDoor();
158
}
159
virtual Light* CreateLight()
160![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
{
161
return new ClassicLight();
162
}
163
}
;
164
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
165
//
Client Code ---- use the Abstract Factory & Abstract Product to create the car
166
//
this is never changed
167
class
CarManager
168
![](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
169
protected:
170
AbstractFactory *abstractFactory;
171
public:
172
//创造Car
173
void createCar(AbstractFactory *abstractFactory)
174![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
{
175
abstractFactory->CreateEngine();
176
abstractFactory->CreateDoor();
177
abstractFactory->CreateLight();
178
}
179
//其他的操作![](https://i-blog.csdnimg.cn/blog_migrate/918e8df969f9f8c8d002f25cda86cade.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/918e8df969f9f8c8d002f25cda86cade.gif)
180![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
void run()
{}
181
}
;
182
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
183
int
_tmain(
int
argc, _TCHAR
*
argv[])
184
![](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
185
CarManager *carManager = new CarManager();
186
//创建Classic风格的汽车
187
carManager->createCar(new ClassicFactory());
188![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
189
return 0;
190
}