这里用到了继承又用到了组合,继承的作用在于:达到“类型匹配”,而不是简单的利用继承获取到“行为”。如果我们以来继承的,那么类的行为只能在编译的时候静态的决定,换句话说就是行为如果不是来自超类就是子类覆盖后的版本,反之,利用组合可以吧装饰者混合着用 而且是在“运行时”。
在上图中,让Decorator继承自Component并不是要继承Component的行为,而是因为装饰者与被装饰者必须是一样的类型(这样装饰者才能取代被装饰者),这是相当关键的地方。在这里,我们利用继承达到“类型匹配”而不是利用继承获得行为。
而装饰者的行为是如何加入的呢?将装饰者与组建组合时,就是在加入行为。所得到的新行为,并不是来自继承,而是由组合对象得来的。
但是,当顾客需要加调料时怎么办呢?如果将加了某种调料的咖啡设计成另外一个类,那么将引起类爆炸。我们采用如下的做法:以饮料为主体,然后在运行时以调料来装饰(decorate)饮料。

StarBuzz.h:
1

#ifndef __STARBUZZ_H__
2

#define __STARBUZZ_H__
3

4

#include <atlstr.h>
5

#include <iostream>
6

using namespace std;
7

8

#ifdef UNICODE
9

#define cout wcout
10

#endif
11

12

13

//定义父类
14

class CBeverage
15



{
16

public:
17

CBeverage()
18


{
19

m_description = _T("Unknow Beverage");
20

m_cost = 0.0F;
21

}
22

23

virtual ~CBeverage()
24


{
25

cout << _T("~CBeverage") << endl;
26

}
27

28

virtual CString GetDescription()
29


{
30

return m_description;
31

}
32

33

virtual float GetCost()
34


{
35

return m_cost;
36

}
37

protected:
38

CString m_description;
39

float m_cost;
40

};
41

42

//定义咖啡类1
43

class CHouseBlend : public CBeverage
44



{
45

public:
46

CHouseBlend()
47


{
48

m_description = _T("HouseBlend");
49

m_cost = 2.4F;
50

}
51

52

~CHouseBlend()
53


{
54

cout << _T("~CHouseBlend") << endl;
55

}
56

57

virtual CString GetDescription()
58


{
59

return m_description;
60

}
61

virtual float GetCost()
62


{
63

return m_cost;
64

}
65

};
66

67

//定义咖啡类2
68

class CDarkRoast : public CBeverage
69



{
70

public:
71


CDarkRoast()/**//*:m_description(_T("HouseBlend")),m_cost(6)*/
72


{
73

m_description = _T("DarkRoast");
74

m_cost = 2.4F;
75

}
76
77

~CDarkRoast()
78


{
79

cout << _T("~CDarkRoast") << endl;
80

}
81

82

virtual CString GetDescription()
83


{
84

return m_description;
85

}
86

virtual float GetCost()
87


{
88

return m_cost;
89

}
90

};
91

92

//定义咖啡类3
93

class CEspresso : public CBeverage
94



{
95

public:
96

CEspresso()
97


{
98

m_description = _T("Espresso");
99

m_cost = 2.4F;
100

}
101

102

~CEspresso()
103


{
104

cout << _T("~CEspresso") << endl;
105

}
106

107

virtual CString GetDescription()
108


{
109

return m_description;
110

}
111

virtual float GetCost()
112


{
113

return m_cost;
114

}
115

};
116

117

//定义咖啡类4
118

class CDecaf : public CBeverage
119



{
120

public:
121

CDecaf()
122


{
123

m_description = _T("Decaf");
124

m_cost = 2.4F;
125

}
126

127

~CDecaf()
128


{
129

cout << _T("~CDecaf") << endl;
130

}
131

132

virtual CString GetDescription()
133


{
134

return m_description;
135

}
136

virtual float GetCost()
137


{
138

return m_cost;
139

}
140

};
141

142

143

//定义调料类
144

class CCondiment : public CBeverage
145



{
146

public:
147

CCondiment()
148


{
149

m_pbeverage = NULL;
150

m_description = _T("Unknow Condiment");
151

m_cost = 0.0F;
152

}
153

~CCondiment()
154


{
155

//这样做不好,因为m_pbeverage所占的内存并不是在这个类中分配的.
156

//不过,如果不这么做,那么在使用的时候会出现泄露
157

delete m_pbeverage;
158

cout << _T("~CCondiment") << endl;
159

}
160

virtual CString GetDescription() = 0;
161

virtual float GetCost() = 0;
162

protected:
163

CBeverage* m_pbeverage;
164

CString m_description;
165

float m_cost;
166

167

};
168

169

170

//具体的调料1
171

class CMilk : public CCondiment
172



{
173

public:
174

CMilk(CBeverage* pbev)//注意,这里是指针
175


{
176

m_pbeverage = pbev;
177

m_description = _T("Milk");
178

m_cost = 2.4F;
179

}
180

181

~CMilk()
182


{
183

cout << _T("~CMilk") << endl;
184

}
185

186

CString GetDescription()
187


{
188

return m_pbeverage->GetDescription() + _T(",") + m_description;
189

}
190

float GetCost()
191


{
192

return m_pbeverage->GetCost() + m_cost;
193

}
194

};
195

196

//具体的调料2
197

class CMocha : public CCondiment
198



{
199

public:
200

CMocha(CBeverage* pbev)
201


{
202

m_pbeverage = pbev;
203

m_description = _T("Mocha");
204

m_cost = 2.5F;
205

}
206

207

~CMocha()
208


{
209

cout << _T("~CMocha") << endl;
210

}
211

212

CString GetDescription()
213


{
214

return m_pbeverage->GetDescription() + _T(",") + m_description;
215

}
216

float GetCost()
217


{
218

return m_pbeverage->GetCost() + m_cost;
219

}
220

};
221

222

//具体的调料3
223

class CSoy : public CCondiment
224



{
225

public:
226

CSoy(CBeverage* pbev)
227


{
228
229

m_pbeverage = pbev;
230

m_description = _T("Soy");
231

m_cost = 2.6F;
232

}
233

234

~CSoy()
235


{
236

cout << _T("~CSoy") << endl;
237

}
238

239

CString GetDescription()
240


{
241

return m_pbeverage->GetDescription() + _T(",") + m_description;
242

}
243

float GetCost()
244


{
245

return m_pbeverage->GetCost() + m_cost;
246

}
247

};
248

249

//具体的调料4
250

class CWhip : public CCondiment
251



{
252

public:
253

CWhip(CBeverage* pbev)
254


{
255
256

m_pbeverage = pbev;
257

m_description = _T("Whip");
258

m_cost = 2.7F;
259

}
260

261

~CWhip()
262


{
263

cout << _T("~CWhip") << endl;
264

}
265

266

CString GetDescription()
267


{
268

return m_pbeverage->GetDescription() + _T(",") + m_description;
269

}
270

float GetCost()
271


{
272

return m_pbeverage->GetCost() + m_cost;
273

}
274

};
275

#endif
1

// StarBuzz-DecoratePatten.cpp : Defines the entry point for the console application.
2

//
3

4

#include "stdafx.h"
5

#include "StarBuzz.h"
6

7

8

int _tmain(int argc, _TCHAR* argv[])
9



{
10

CBeverage* pbeverage = new CHouseBlend();
11

pbeverage = new CMilk(pbeverage);
12

pbeverage = new CSoy(pbeverage);
13

pbeverage = new CWhip(pbeverage);
14

pbeverage = new CMocha(pbeverage);
15

16

cout << (LPCTSTR)pbeverage->GetDescription() << _T(": ")<< pbeverage->GetCost() << endl;
17

18

delete pbeverage;
19

20

return 0;
21

}
22

23
