觀察者模式是設(shè)計模式中行為模型的一種,,是定義對象間的一種一對多的依賴關(guān)系,,以便當(dāng)一個對象的狀態(tài)發(fā)生改變時,,所有依賴于它的對象都得到通知并自動刷新,。 1using System; 2 3namespace DelegateEvent 4 5{ 6 7 /// <summary> 8 9 /// Subject 的摘要說明。 10 11 /// 被觀察者抽象基類 12 13 /// 所有被觀察者對象都繼承此類 14 15 /// 做為抽象基類,,此類不允許直接進(jìn)行實例化 16 17 /// 此類中首先定義委托 18 19 /// 再有委托定義事件 20 21 /// 然后創(chuàng)立與委托想關(guān)聯(lián)的方法Notify 22 23 /// </summary> 24 25 public abstract class Subject 26 27 { 28 29 public Subject() 30 31 { 32 33 // 34 35 // TODO: 在此處添加構(gòu)造函數(shù)邏輯 36 37 // 38 39 } 40 41 /// <summary> 42 43 /// 創(chuàng)建一個委托 44 45 /// </summary> 46 47 public delegate void SubEventHandler(); 48 49 /// <summary> 50 51 /// 根據(jù)SubEventHandler創(chuàng)建一個事件 52 53 /// </summary> 54 55 public event SubEventHandler SubEvent; 56 57 /// <summary> 58 59 /// 將于委托相連接的方法 60 61 /// </summary> 62 63 protected void Notify() 64 65 { 66 67 if(this.SubEvent!=null) 68 69 this.SubEvent(); 70 71 } 72 73 } 74 75} 76 77//------------------------------------------------------------------------------------------ 78 79被觀察者基類完成后我們再來創(chuàng)建觀察者基類Observer. 80 81namespace DelegateEvent 82 83{ 84 85 /// <summary> 86 87 /// Observer 的摘要說明,。 88 89 /// 觀察者抽象基類 90 91 /// 所有觀察者對象都由此類派生 92 93 /// 使用此類進(jìn)行對事件的注冊 94 95 /// 并和事件的方法關(guān)聯(lián) 96 97 /// 另外定義了一個抽象方法Response 98 99 /// 可以由子類來進(jìn)行覆蓋 100 101 /// </summary> 102 103 public abstract class Observer 104 105 { 106 107 public Observer(Subject childModel) 108 109 { 110 111 //注冊SubEvent事件通過SubEventHandler委托和Response方法關(guān)聯(lián) 112 113 //子類通過調(diào)用此構(gòu)造函數(shù)完成事件的注冊 114 115 childModel.SubEvent+=new Subject.SubEventHandler(Response); 116 117 } 118 119 120 121 /// <summary> 122 123 /// 抽象方法,用于引發(fā)事件 124 125 /// </summary> 126 127 public abstract void Response(); 128 129 } 130 131} 132 133同理,,我們還可以繼續(xù)創(chuàng)建另一個觀察者基類,,用來響應(yīng)不同的事件的方法。 134 135namespace DelegateEvent 136 137{ 138 139 /// <summary> 140 141 /// Observer2 的摘要說明,。 142 143 /// 注冊了兩個事件的方法,。 144 145 /// </summary> 146 147 public abstract class Observer2 148 149 { 150 151 public Observer2(Subject childModel) 152 153 { 154 155 childModel.SubEvent+=new Subject.SubEventHandler(Response); 156 157 childModel.SubEvent+=new Subject.SubEventHandler(Response2); 158 159 } 160 161 public abstract void Response(); 162 163 public abstract void Response2(); 164 165 } 166 167} 168 169//------------------------------------------------------------------------------------------------------- 170 171現(xiàn)在,,我們來針對這個實例中的貓大叫這個引發(fā)事件進(jìn)行解析。 172 173namespace DelegateEvent 174 175{ 176 177 /// <summary> 178 179 /// Cat 的摘要說明,。 180 181 /// 此類作為被觀察者對象 182 183 /// 直接繼承Subject類 184 185 /// 使用一個Cry方法,,調(diào)用Notify方法起用先前定義的SubEvent事件 186 187 /// </summary> 188 189 public class Cat:Subject 190 191 { 192 193 public Cat() 194 195 { 196 197 // 198 199 // TODO: 在此處添加構(gòu)造函數(shù)邏輯 200 201 // 202 203 } 204 205 public void Cry() 206 207 { 208 209 System.Console.WriteLine("Cat Cry.."); 210 211 //調(diào)用從ModelBase繼承過來的Notify() 212 213 this.Notify(); 214 215 } 216 217 } 218 219} 220 221// 這樣一個被觀察者對象就完成了。 222 223//-------------------------------------------------------------------------------------------------------------------- 224 225被觀察者對象有了,,我們再來創(chuàng)建具體的觀察者對象,。此例中,有主人,,小孩和老鼠對貓的叫聲做出了反應(yīng),,因此我們可以創(chuàng)建三個類,分別對主人,、小孩和老鼠進(jìn)行響應(yīng),。其中,主人和老鼠對應(yīng)Observer類,,響應(yīng)其中的一個事件,;而小孩則繼承Observer2類,響應(yīng)其中的兩個事件,。 226 227//------------------------------------觀察者--主人類--------------------------------------------------- 228 229namespace DelegateEvent 230 231{ 232 233 /// <summary> 234 235 /// Master 的摘要說明,。 236 237 /// </summary> 238 239 public class Master:Observer 240 241 { 242 243 /// <summary> 244 245 /// 構(gòu)造函數(shù),接受一個Cat類型的對象childModel并強制轉(zhuǎn)換為基類ModelBase變量 246 247 /// 再將childModel傳入到父類Observer的構(gòu)造函數(shù)當(dāng)中,,實現(xiàn)注冊,。 248 249 /// </summary> 250 251 /// <param name="childModel"></param> 252 253 public Master(Subject childModel):base(childModel) 254 255 { 256 257 258 259 } 260 261 public override void Response() 262 263 { 264 265 System.Console.WriteLine("主人醒來"); 266 267 } 268 269 } 270 271} 272 273//------------------------------------觀察者--老鼠類----------------------------------------------------- 274 275namespace DelegateEvent 276 277{ 278 279 /// <summary> 280 281 /// Mouse 的摘要說明。 282 283 /// </summary> 284 285 public class Mouse:Observer 286 287 { 288 289 private string name; 290 291 public Mouse(string name, Subject childModel):base(childModel) 292 293 { 294 295 this.name=name; 296 297 } 298 299 300 301 //覆蓋Observer類Response方法 302 303 public override void Response() 304 305 { 306 307 System.Console.WriteLine(this.name+"開始逃跑"); 308 309 } 310 311 } 312 313} 314 315//于主人類不同的是,,老鼠類的構(gòu)造函數(shù)可以接受一個字符串參數(shù),,這樣可以變的更多樣化 316 317//------------------------------------觀察者--小孩------------------------------------------------------------ 318 319namespace DelegateEvent 320 321{ 322 323 /// <summary> 324 325 /// Child 的摘要說明。 326 327 /// </summary> 328 329 public class Child:Observer2 330 331 { 332 333 public Child(Subject childBase):base(childBase) 334 335 { 336 337 338 339 } 340 341 public override void Response() 342 343 { 344 345 Console.WriteLine("baby醒來,。,。。,。"); 346 347 } 348 349 public override void Response2() 350 351 { 352 353 Console.WriteLine("開始哭鬧,。。,。,。。"); 354 355 } 356 357 } 358 359} 360 361//小孩類里,,由于繼承的是Observer2類,,因此可以響應(yīng)兩種不同的方法。 362 363在主函數(shù)里,,定義每個觀察者子類的對象,,由其構(gòu)造函數(shù)接受被觀察者對象進(jìn)行事件的響應(yīng),。 364 365namespace DelegateEvent 366 367{ 368 369 /// <summary> 370 371 /// SubMain 的摘要說明。 372 373 /// </summary> 374 375 public class SubMain 376 377 { 378 379 public SubMain() 380 381 { 382 383 384 385 } 386 387 /// <summary> 388 389 /// 主函數(shù),,定義子類對象 390 391 /// </summary> 392 393 public static void Main() 394 395 { 396 397 Cat myCat=new Cat(); 398 399 Mouse myMouse1=new Mouse("mouse1",myCat); 400 401 Mouse myMouse2=new Mouse("mouse2",myCat); 402 403 Master myMaster=new Master(myCat); 404 405 406 407 Child myLittleMaster=new Child(myCat); 408 409 myCat.Cry(); 410 411 } 412 413 } 414 415} 416 417 改變一下應(yīng)用環(huán)境: 老鼠偷油,,貓來捉老鼠,老鼠嚇跑,,打碎了油瓶,,人被吵醒。 這樣的一個環(huán)境下,,如何使用觀察者模式呢,? 首先區(qū)分,誰是一整串事件的引發(fā)者,,可以分析是老鼠,,老鼠偷油這件事情引發(fā)了一系列事件。 貓作為老鼠的觀察者,,當(dāng)老鼠偷油這件事情發(fā)生以后,,觸發(fā)貓捉老鼠的事件,而下面思維開始混亂,,因為老鼠逃跑,,打翻油瓶這件事按理論來說應(yīng)該不是直接由老鼠偷油這件事情引發(fā)的,而是由貓捉老鼠這件事情,。因此在貓捉老鼠,,老鼠逃跑的事件中,又似乎是貓是被觀察者,,而老鼠是觀察者,。但這樣理解的話,是不是就形成一種循環(huán)了亞,。 但細(xì)細(xì)想來,上面這個問題又是自欺欺人,,因為首先觀察者模式是希望實現(xiàn)一個對象的狀態(tài)發(fā)生改變時,,所有依賴于它的對象都得到通知并自動刷新。 從上面情形來看,,老鼠逃跑只是這個鏈上的一個節(jié)點,,而這個節(jié)點的事件發(fā)起人正是被觀察者,因此又出現(xiàn)下列問題,,被觀察者能否依賴于其本身呢,?只要是能依賴,這樣一個情形,,使用觀察者模性就是合理的,。但是假使這樣可行的話,,那么觀察者和被觀察者之間是否又沒有了清晰的界限,加大了對象之間的耦合關(guān)系,,這是不是又違背OO思想,?希望大家給點意見。 上述情形實現(xiàn)代碼如下: result:
|
|