1
Observer设计模式#region Observer设计模式
2
/**//*
3
* 假设热水器由三部分组成:热水器、警报器、显示器,它们来自于不同厂商并进行了组装。那么应该是热水器仅仅负责烧水,它不能发出警报也不能显示水温;
4
* 在水烧开时由警报器发出警报、显示器显示提示和水温。
5
*
6
* Observer设计模式中主要包括如下两类对象:
7
* (1)Subject: 监视对象,它往往包含着其它对象所感兴趣的内容。在本范例中,热水器就是一个监视对象,它包含的其它对象所感兴趣的内容,就是temprature
8
* 字段,当这个字段的值快到100时,会不断把数据发给监视它的对象。
9
* (2)Observer: 监视者,它监视Subject,当Subject中的某件事发生的时候,会告知Observer,而Observer则会采取相应的行动。在本范例中,Observer有警报器
10
* 和显示器,它们采取的行动分别是发出警报和显示水温。
11
*
12
* 在本例中,事情发生的顺序应该是这样的:
13
* (1)警报器和显示器告诉热水器,它对它的温度比较感兴趣(注册)。
14
* (2)热水器知道后保留对警报器和显示器的引用。
15
* (3)热水器进行烧水这一动作,当水温超过95度时,通过对警报器和显示器的引用,自动调用警报器的MakeAlert()方法、显示器的ShowMsg()方法。
16
*
17
* 类似这样的例子是很多的,GOF对它进行了抽象,称为Observer设计模式:Observer设计模式是为了定义对象间的一种一对多的依赖关系,以便于当一个对象的
18
* 状态改变时,其它依赖于它的对象会被自动告知并更新。Observer模式是一种松耦合的设计模式。
19
*
20
* .Net Framework中的委托与事件
21
* 尽管上面的范例很好第完成了我们想要完成的工作,但是我们不仅疑惑:为什么.Net Framework中的事件模型与上面的不同?为什么有很多的EventArgs参数?
22
* 在回答上面的问题之前,我们先搞懂.Net Framework的编码规范:
23
* (1)委托类型的名称都应该以EventHandler结束。
24
* (2)委托的原型定义:有一个void返回值,并接受两个输入参数:一个Object类型,一个EventArgs类型(或继承自EventArgs)。
25
* (3)事件的命名为:委托去掉EventHandler之后剩余的部分。
26
* (4)继承自EventArgs的类型应该以EventArgs结尾。
27
*
28
* 再做一下说明:
29
* (1)委托声明原型中的Object类型的参数代表了Subject,也就是监视对象,在本例中是Heater(热水器)。回调函数(比如 Alarm的MakeAlert)可以通过它
30
* 访问触发事件的对象(Heater)。
31
* (2)EventArgs对象包含了Observer所感兴趣的数据,在本例中是temperature。
32
*
33
* 上面这些其实不仅仅是为了编码规范而已,这样也使得程序有更大的灵活性。比如说,我们不光想获得热水器的温度,还想在Observer端(警报器或者显示器)
34
* 方法中获得它的生产日期、型号、价格,那么委托和方法的声明都会变得麻烦,而如果我们将热水器的引用传给警报器方法,就可以在方法中直接访问热水器了。
35
*
36
*/
37
#endregion
38
using System;
39
using System.Collections.Generic;
40
using System.Text;
41
42
namespace ObserverMode
43

{
44
非Observer设计模式#region 非Observer设计模式
45
//class Heater
46
//{
47
// private int temperature;
48
49
// //烧水
50
// public void BoilWater()
51
// {
52
// for (int i = 0; i <= 100; i++)
53
// {
54
// temperature = i;
55
// if (temperature > 95)
56
// {
57
// MakeAlert(temperature);
58
// ShowMsg(temperature);
59
// }
60
// }
61
// }
62
63
// //发出语音警报
64
// private void MakeAlert(int param)
65
// {
66
// Console.WriteLine("Alarm:嘀嘀嘀,水已经{0}度了。", param);
67
// }
68
69
// //显示水温
70
// private void ShowMsg(int param)
71
// {
72
// Console.WriteLine("Display:水快开了,当前温度:{0}度。", param);
73
// }
74
//}
75
76
//class Program
77
//{
78
// static void Main(string[] args)
79
// {
80
// Heater ht = new Heater();
81
// ht.BoilWater();
82
// Console.ReadLine();
83
// }
84
//}
85
#endregion
86
87
Observer设计模式#region Observer设计模式
88
89
/**/////热水器
90
//public class Heater
91
//{
92
// private int temperature;
93
// public delegate void BoilHandler(int param); //声明委托
94
// public event BoilHandler BoilEvent; //声明事件
95
96
// //烧水
97
// public void BoilWater()
98
// {
99
// for (int i = 0; i <= 100; i++)
100
// {
101
// temperature = i;
102
103
// if (temperature > 95)
104
// {
105
// if (BoilEvent != null) //如果有对象注册
106
// {
107
// BoilEvent(temperature); //调用所有注册对象的方法
108
// }
109
// }
110
// }
111
// }
112
//}
113
114
/**/////警报器
115
//public class Alarm
116
//{
117
// public void MakeAlert(int param)
118
// {
119
// Console.WriteLine("Alarm:嘀嘀嘀,水已经{0}度。", param);
120
// }
121
//}
122
123
/**/////显示器
124
//public class Display
125
//{
126
// public static void ShowMsg(int param) //静态方法
127
// {
128
// Console.WriteLine("Display:水已烧开,当前温度:{0}度。", param);
129
// }
130
//}
131
132
//class Program
133
//{
134
// static void Main(string[] args)
135
// {
136
// Heater heater = new Heater();
137
// Alarm alarm = new Alarm();
138
139
// heater.BoilEvent += alarm.MakeAlert; //注册方法
140
// heater.BoilEvent += (new Alarm()).MakeAlert; //给匿名对象注册方法
141
// heater.BoilEvent += Display.ShowMsg; //注册静态方法
142
// heater.BoilWater(); //烧水,会自动调用注册对象的方法
143
// Console.ReadLine();
144
// }
145
//}
146
#endregion
147
148
符合.Net Framework规范的Observer设计模式#region 符合.Net Framework规范的Observer设计模式
149
150
//热水器
151
public class Heater
152
{
153
private int temperature;
154
public string type = "RealFile 001"; //添加型号作为演示
155
public string area = "China Xian"; //添加产地作为演示
156
157
//定义BoiledEventArgs类,传递给Observer所感兴趣的信息
158
public class BoiledEventArgs : EventArgs
159
{
160
public readonly int temperature;
161
public BoiledEventArgs(int temperature)
162
{
163
this.temperature = temperature;
164
}
165
}
166
167
//声明委托
168
public delegate void BoiledEventHandler(Object sender, BoiledEventArgs e);
169
public event BoiledEventHandler Boiled; //声明事件
170
171
//可以供继承自Heater的类重写,以便继承类拒绝其它对象对它的监视
172
protected virtual void OnBolied(BoiledEventArgs e)
173
{
174
if (Boiled != null)
175
{
176
Boiled(this, e);
177
}
178
}
179
180
//烧水
181
public void BoilWater()
182
{
183
for (int i = 0; i <= 100; i++)
184
{
185
temperature = i;
186
if (temperature > 95)
187
{
188
//建立BoiledEventArgs对象。
189
BoiledEventArgs e = new BoiledEventArgs(temperature);
190
OnBolied(e); //调用OnBoiled方法
191
}
192
}
193
}
194
}
195
196
//警报器
197
public class Alarm
198
{
199
public void MakeAlert(Object sender, Heater.BoiledEventArgs e)
200
{
201
Heater heater = (Heater)sender;
202
//访问sender中的公共字段
203
Console.WriteLine("Alarm:{0} - {1}:", heater.area, heater.type);
204
Console.WriteLine("Alarm:嘀嘀嘀,水已经{0}度了:", e.temperature);
205
Console.WriteLine();
206
}
207
}
208
209
//显示器
210
public class Display
211
{
212
public static void ShowMsg(object sender, Heater.BoiledEventArgs e)
213
{
214
Heater heater = (Heater)sender;
215
Console.WriteLine("Display:{0} - {1}:", heater.area, heater.type);
216
Console.WriteLine("Display:水快烧开了,当前温度:{0}度。", e.temperature);
217
Console.WriteLine();
218
}
219
}
220
221
class Program
222
{
223
static void Main(string[] args)
224
{
225
Heater heater = new Heater();
226
Alarm alarm = new Alarm();
227
228
heater.Boiled += alarm.MakeAlert; //注册方法
229
heater.Boiled += (new Alarm()).MakeAlert; //给匿名对象注册方法
230
heater.Boiled += new Heater.BoiledEventHandler(alarm.MakeAlert); //也可以这么注册
231
heater.Boiled += Display.ShowMsg; //注册静态方法
232
heater.BoilWater();
233
Console.ReadLine();
234
}
235
}
236
237
#endregion
238
}
239


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

191

192

193

194

195

196

197

198



199

200



201

202

203

204

205

206

207

208

209

210

211



212

213



214

215

216

217

218

219

220

221

222



223

224



225

226

227

228

229

230

231

232

233

234

235

236

237

238

239
