設計模式之AbstractFactory模式
設計模式的目的就是盡量減少“變化”對程序的影響,尤其是對客戶程序的影響。AbstractFactory模式作為創建型模式的一種,解決的就是“new”在變化中可能引起的問題。先來看看new有何種不好,舉個創建汽車的車門的例子:
很自然的一種想法是:Door *door = new Door();
但是如果遇到創建老爺車的車門,創建現代車的車門,這段代碼就無所適從了。
OO為我們提供了哪些精華的思想?“封裝”,是的,將車門的創建封裝起來,于是我們有了靜態工廠方法:
客戶程序代碼:
1
Door* door = doorFactory->CreateDoor();
庫程序代碼:
1
class DoorFactory
2

{
3
public:
4
Door* CreateDoor()
5
{
6
return new Door();
7
}
8
}

2



3

4

5



6

7

8

客戶程序在此是不會變化的,不管你是老爺車門,現代車門,還是鉆石車門,這些和客戶程序代碼都是沒關系的,究竟CreateDoor出來如何結果都交給多態來判斷,我們不用操心。
但是庫程序代碼還是需要更改的,但我們已經將“變化”與客戶程序隔離了。
需求又有變化了,不光要創建車門,還需要創建引擎,車燈,而且還是不同風格的。
這時候靜態工廠已經應付不來了,靜態工廠有其自身的缺陷“不能應對不同系列對象”的變化。
動機:
軟件系統中,經常面臨“一系列相互依賴的對象”的創建工作。(兩個特征:“一系列”,“相互依賴”)
將創建過程封裝起來,避免“客戶程序”和“多系列具體對象的創建工作”的緊耦合。
意圖:
提供一個接口,讓該接口負責創建一系列“相關或者相互依賴的對象”,無需指定他們具體的類。(GoF23)
思路:
對于客戶程序來說,只依賴于三個抽象的類:AbstractFactory,AbstractProductA,AbstractProductB。
以下是客戶程序代碼:
1
class CarManager
2

{
3
protected:
4
AbstractFactory *abstractFactory;
5
public:
6
//創造Car
7
void createCar(AbstractFactory *abstractFactory)
8
{
9
abstractFactory->CreateEngine();
10
abstractFactory->CreateDoor();
11
abstractFactory->CreateLight();
12
}
13
//其他的操作

14
void run()
{}
15
};
16
17
int _tmain(int argc, _TCHAR* argv[])
18

{
19
CarManager *carManager = new CarManager();
20
//創建Classic風格的汽車
21
carManager->createCar(new ClassicFactory());
22
23
return 0;
24
}
所有關于創建的操作都是用抽象類完成的,對于具體是何種類型的對象由多態實現,以此來使“客戶代碼”和“多系列具體對象的創建工作”達到松耦合。
2



3

4

5

6

7

8



9

10

11

12

13



14



15

16

17

18



19

20

21

22

23

24

如果遇到還需要擴展其他風格的汽車,可以按下圖的思路
紅色的部分對應新風格的車輛,只需在庫程序中添加ConcreteFactory3,ProductA3,ProductB3三個類,而對于客戶代碼CarManager來說完全不受影響。
總結:
AbstractFactory模式有以下三個要點:
1.應對的問題是“多風格的系列對象創建”的變化問題,“系列對象”指的是這些對象之間有相互依賴或者相互作用的關系。否則使用“靜態工廠”足以。
2.抽象工廠和靜態工廠的核心是“封裝”,將對象的創建進行封裝,避免“new”引起的問題
3.抽象工程的另一個核心是“多態”,通過動態綁定來處理“不同風格”的問題
注:
AbstractFactory模式主要針對“風格”的變化,如果“對象”本身經常變化,那么該模式并不適用。
自己做的示例代碼,僅供參考
1
/**///////////////////////////////////////////////////////////////////////////
2
// AbstractFactoryTest for AbstractFactory Pattern Test
3
//
4
/**///////////////////////////////////////////////////////////////////////////
5
6
#include "stdafx.h"
7
#include "iostream"
8
using namespace std;
9
10
//Engine,Door,Light are the Abstract Product
11
//這三個類對應UML圖中的AbstractProduct類
12
class Engine
13

{
14
public:
15
Engine()
16
{
17
cout<<"Abstract Engine Create"<<endl;
18
}
19
virtual void doSomething() = 0;
20
};
21
22
class Door
23

{
24
public:
25
Door()
26
{
27
cout<<"Abstract Door Create"<<endl;
28
}
29
virtual void doSomething() = 0;
30
};
31
32
class Light
33

{
34
public:
35
Light()
36
{
37
cout<<"Abstract Light Create"<<endl;
38
}
39
virtual void doSomething() = 0;
40
};
41
42
//Abstract Factory
43
class AbstractFactory
44

{
45
public:
46
AbstractFactory()
47
{
48
cout<<"AbstractFactory Create"<<endl;
49
}
50
virtual Engine* CreateEngine() = 0;
51
virtual Door* CreateDoor() = 0;
52
virtual Light* CreateLight() = 0;
53
};
54
55
//SpeedEngine,SpeedDoor,SpeedLight are the Products of Speed Style
56
//這三個類對應UML圖中的ProductA1,ProductB1,ProductC1類
57
class SpeedEngine:public Engine
58

{
59
public :
60
SpeedEngine()
61
{
62
cout<<"Speed Engine Create"<<endl;
63
}
64
void doSomething()
{ }
65
};
66
67
class SpeedDoor:public Door
68

{
69
public :
70
SpeedDoor()
71
{
72
cout<<"Speed Door Create"<<endl;
73
}
74
void doSomething()
{ }
75
};
76
77
class SpeedLight:public Light
78

{
79
public :
80
SpeedLight()
81
{
82
cout<<"Speed Light Create"<<endl;
83
}
84
void doSomething()
{ }
85
};
86
87
//classicEngine,classicDoor,classicLight are the products of Classic style
88
//這三個類對應UML圖中的ProductA2,ProductB2,ProductC2類
89
class ClassicEngine:public Engine
90

{
91
public :
92
ClassicEngine()
93
{
94
cout<<"Classic Engine Create"<<endl;
95
}
96
void doSomething()
{ }
97
};
98
99
class ClassicDoor:public Door
100

{
101
public :
102
ClassicDoor()
103
{
104
cout<<"Classic Door Create"<<endl;
105
}
106
void doSomething()
{ }
107
};
108
109
class ClassicLight:public Light
110

{
111
public :
112
ClassicLight()
113
{
114
cout<<"Classic Light Create"<<endl;
115
}
116
void doSomething()
{ }
117
};
118
119
//Factory for Speed Cars
120
//對應UML圖中的ConcreteFactory1類
121
class SpeedFactory:public AbstractFactory
122

{
123
public:
124
SpeedFactory()
125
{
126
cout<<"SpeedFactory Create"<<endl;
127
}
128
virtual Engine* CreateEngine()
129
{
130
return new SpeedEngine();
131
}
132
virtual Door* CreateDoor()
133
{
134
return new SpeedDoor();
135
}
136
virtual Light* CreateLight()
137
{
138
return new SpeedLight();
139
}
140
};
141
142
//Factory for classic Cars
143
//對應UML圖中的ConcreteFactory2類
144
class ClassicFactory:public AbstractFactory
145

{
146
public:
147
ClassicFactory()
148
{
149
cout<<"ClassicFactory Create"<<endl;
150
}
151
virtual Engine* CreateEngine()
152
{
153
return new ClassicEngine();
154
}
155
virtual Door* CreateDoor()
156
{
157
return new ClassicDoor();
158
}
159
virtual Light* CreateLight()
160
{
161
return new ClassicLight();
162
}
163
};
164
165
//Client Code ---- use the Abstract Factory & Abstract Product to create the car
166
//this is never changed
167
class CarManager
168

{
169
protected:
170
AbstractFactory *abstractFactory;
171
public:
172
//創造Car
173
void createCar(AbstractFactory *abstractFactory)
174
{
175
abstractFactory->CreateEngine();
176
abstractFactory->CreateDoor();
177
abstractFactory->CreateLight();
178
}
179
//其他的操作

180
void run()
{}
181
};
182
183
int _tmain(int argc, _TCHAR* argv[])
184

{
185
CarManager *carManager = new CarManager();
186
//創建Classic風格的汽車
187
carManager->createCar(new ClassicFactory());
188
189
return 0;
190
}


2

3

4


5

6

7

8

9

10

11

12

13



14

15

16



17

18

19

20

21

22

23



24

25

26



27

28

29

30

31

32

33



34

35

36



37

38

39

40

41

42

43

44



45

46

47



48

49

50

51

52

53

54

55

56

57

58



59

60

61



62

63

64



65

66

67

68



69

70

71



72

73

74



75

76

77

78



79

80

81



82

83

84



85

86

87

88

89

90



91

92

93



94

95

96



97

98

99

100



101

102

103



104

105

106



107

108

109

110



111

112

113



114

115

116



117

118

119

120

121

122



123

124

125



126

127

128

129



130

131

132

133



134

135

136

137



138

139

140

141

142

143

144

145



146

147

148



149

150

151

152



153

154

155

156



157

158

159

160



161

162

163

164

165

166

167

168



169

170

171

172

173

174



175

176

177

178

179



180



181

182

183

184



185

186

187

188

189

190

posted on 2009-04-06 21:20 Alex@VCC 閱讀(1670) 評論(2) 編輯 收藏 引用 所屬分類: 設計模式