Observer设计模式-------3
Observer设计模式主要包括两类对象:
1.Subject:监视对象,其往往包含其他对象感兴趣的内容。在烧水报警模型中,热水器就是一个监视对象。它包含其他对象感兴趣的内容,temprature字段。
2.Observer:监视者,他见识Subject,当Subject中某事件发生时,会告知Observer,而Observer会采取相应行动。
在烧水报警中事情发生顺序:
1.警报器和显示器告诉热水器,它对它的温度感兴趣(注册)。
2.热水器知道后保留对警报器和显示器的引用。
3.热水器进行烧水这一动作,当水温超过95度,通过警报器和显示器的引用,自动调用警报器和显示器中相应方法。
using System; using System.Collections.Generic; using System.Text; namespace Delegate { //热水器 public class Heater { private int temperature; public delegate void BoilHandler(int param);//声明委托 public event BoilHandler BoilEvent;//声明事件 //烧水 public void BoilWater() { for(int i=0;i<=100;i++) { temperature = i; if(temperature>95) { if(BoilEvent!=null) { BoilEvent(temperature); } } } } } //警报器 public class Alarm { public void MakeAlert(int param) { Console.WriteLine("Alarm:嘀嘀嘀,水已经{0}度了",param); } } //显示器 public class Display { public static void ShowMsg(int param) { Console.WriteLine("Display:嘀嘀嘀,水已经{0}度了", param); } } class Program { static void Main() { Heater heater = new Heater(); ; Alarm alarm=new Alarm(); //heater.BoilEvent += alarm.MakeAlert; heater.BoilEvent += (new Alarm()).MakeAlert; heater.BoilEvent += Display.ShowMsg; heater.BoilWater(); } } }
framework编码规范:
1.委托类型的名称都应该依EventHandler结束。
2.委托的原型第一:有一个void返回值,并接受两个输入参数:一个Object类型,一个EventArgs类型(或继承自EventArgs)。
3.事件的命名为委托去掉EventHandler之后剩余的部分。
4.继承自EvenArgs的类型应该以EventArgs结尾。
结合上面例子
委托原型中的Object类型的参数代表了Subject,即监视对象,本例中时Heater。回调函数(如Alarm的MakeAlert)可以通过它访问触发事件的对象(Heater)。
EventArgs对象包含了Observer所感兴趣的数据,在本例中时temperature
using System; using System.Collections.Generic; using System.Text; namespace Delegate { //热水器 public class Heater { private int temperature; public string type = "RealFire 001"; public string area = "China Xian"; public delegate void BoilEventHandler(Object sender,BoiledEventArgs e);//声明委托 public event BoilEventHandler Boiled;//声明事件 //定义BoiledEventArgs类,传输给Observer所感兴趣的信息 public class BoiledEventArgs:EventArgs { public readonly int temperature; public BoiledEventArgs(int temperature) { this.temperature = temperature; } } //可以供继承自Heater的类重写,以便继承类拒绝其他对象对它的监视 protected virtual void OnBoiled(BoiledEventArgs e) { if(Boiled!=null) { Boiled(this, e); } } //烧水 public void BoilWater() { for(int i=0;i<=100;i++) { temperature = i; if(temperature>95) { BoiledEventArgs e=new BoiledEventArgs(temperature); OnBoiled(e); } } } } //警报器 public class Alarm { public void MakeAlert(Object sender,Heater.BoiledEventArgs e) { Heater heater = (Heater) sender; //访问sender中的公共字段 Console.WriteLine("Alarm:嘀嘀嘀,水已经{0}度了", e.temperature); } } //显示器 public class Display { public static void ShowMsg(Object sender, Heater.BoiledEventArgs e) { Heater heater = (Heater)sender; Console.WriteLine("Display:嘀嘀嘀,水已经{0}度了", e.temperature); } } class Program { static void Main() { Heater heater = new Heater(); ; Alarm alarm=new Alarm(); //heater.BoilEvent += alarm.MakeAlert; heater.Boiled += (new Alarm()).MakeAlert; heater.Boiled += new Heater.BoilEventHandler(alarm.MakeAlert);//也可以这么注册 heater.Boiled += Display.ShowMsg; heater.BoilWater(); } } }