首页 > 代码库 > C#委托与事件之观察者Observer设计模式

C#委托与事件之观察者Observer设计模式

前言

   委托:

委托是一种在对象里保存方法引用的类型,同时也是一种类型安全的函数指针。

或委托可以看成一种表示函数的数据类型,类似函数指针.

事件是特殊的委托
观察者模式:
两种角色:
(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设计模式