標籤:
前言
委託:
委託是一種在對象裡儲存方法引用的類型,同時也是一種型別安全的函數指標。
或委託可以看成一種表示函數的資料類型,類似函數指標.
事件是特殊的委託
觀察者模式:
兩種角色:
(1)Subject, 主題(被監視對象),它往往包含著 Observer 所感興趣的內容。
(2)Observer, 觀察者,它觀察 Subject。 當 Subject 中的某件事發生的時候(通常是它所感興趣的內容改變的時候),會被自動告知,而 Observer 則會採取相應的行動(通常為更新自身狀態或者顯示輸出)。
1、Observer觀察者模式:兩種身份即監視者和被監視者,是一對多的關係。
(1)被監視者即委託事件的發行者也就是定義委託事件的一方。
(2)監視者即委託事件的訂閱者。
2、編碼規範:
(1)委託類型的名稱都應該以EventHandler結束;
(2)委託的原型定義有一個void傳回值,並接受兩個輸入參數,一個是Object,另一個是EventArgs類型(或繼承自EventArgs)。
(3)事件的命名為委託去掉EventHandler之後剩餘的部分。
(4)繼承自EventArgs的類型應該以EventArgs結尾。
3、簡單以“熱水器加熱水,水溫大於95度時通報器響起,顯示器顯示水溫”為例。
Code:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace dotNet之美__委託與事件__Observer觀察者模式2 7 { 8 /// <summary> 9 /// 此例子是:熱水器加熱水,水溫大於95度時通報器響起,顯示器顯示水溫。 10 /// </summary> 11 class Program 12 { 13 static void Main(string[] args) 14 { 15 Heater heater = new Heater(); 16 //訂閱事件 17 heater.Boiled += new Alarm().AlarmAlert; 18 heater.Boiled += new Display().ShowMsg; 19 //也可以這樣訂閱 20 heater.Boiled += new Heater.BoiledEventHandler(new Alarm().AlarmAlert); 21 heater.BoilWater(); 22 Console.ReadLine(); 23 } 24 } 25 /// <summary> 26 /// 委託與事件實現:觀察者設計模式(兩種角色:監視者和被監視者) 27 /// </summary> 28 class Heater//被監視者(委託事件發行者) 29 { 30 //定義訂閱者感興趣的資訊,比如:水溫、熱水器類型以及產地 31 //定義水溫 32 private int temperature; 33 //熱水器類型 34 public string type = "ReadFire 001"; 35 //產地 36 public string area = "China Guangzhou"; 37 /// <summary> 38 /// 聲明一個委託類型 39 /// </summary> 40 /// <param name="sender">發行者對象</param> 41 /// <param name="e">訂閱者感興趣的資訊參數</param> 42 public delegate void BoiledEventHandler(Object sender,BoiledEventArgs e); 43 /// <summary> 44 /// 定義委託事件 45 /// </summary> 46 public event BoiledEventHandler Boiled; 47 /// <summary> 48 /// 訂閱者感興趣的資訊 49 /// </summary> 50 public class BoiledEventArgs : EventArgs 51 { 52 public readonly int temperature; 53 public BoiledEventArgs(int temperature) 54 { 55 this.temperature = temperature; 56 } 57 } 58 /// <summary> 59 /// 觸發的事件 60 /// </summary> 61 /// <param name="e"></param> 62 public void OnBoiled(BoiledEventArgs e) 63 { 64 if (Boiled != null) 65 { 66 Boiled(this, e); 67 } 68 } 69 /// <summary> 70 /// 觸發動作 71 /// </summary> 72 public void BoilWater() 73 { 74 for (int i = 0; i <= 100; i++) 75 { 76 this.temperature = i; 77 if (this.temperature > 95) 78 { 79 BoiledEventArgs e = new BoiledEventArgs(this.temperature); 80 OnBoiled(e); 81 } 82 } 83 } 84 } 85 /// <summary> 86 /// 訂閱者 87 /// </summary> 88 class Alarm 89 { 90 /// <summary> 91 /// 警示 92 /// </summary> 93 /// <param name="sender">發行者即被監視者對象</param> 94 /// <param name="e">感興趣的資訊</param> 95 public void AlarmAlert(Object sender, Heater.BoiledEventArgs e) 96 { 97 Heater heater = (Heater)sender; 98 Console.WriteLine("Alarm:{0}-{1}", heater.area, heater.type); 99 Console.WriteLine("Alarm:嘀嘀嘀···水溫:" + e.temperature);100 } 101 }102 /// <summary>103 /// 訂閱者104 /// </summary>105 class Display106 {107 /// <summary>108 /// 顯示溫度109 /// </summary>110 /// <param name="sender">發行者即被監視者對象</param>111 /// <param name="e">感興趣的資訊</param>112 public void ShowMsg(Object sender, Heater.BoiledEventArgs e)113 {114 Heater heater = (Heater)sender;115 Console.WriteLine("Display:{0}-{1}", heater.area, heater.type);116 Console.WriteLine("水快被燒開了,水溫:" + e.temperature);117 } 118 }119 }
運行結果:
C#委託與事件之觀察者Observer設計模式