C#中的委托和事件:假设热水器由三部分组成:加热器、警报器、显示器,它们来自于不同厂商并进行了组装。 那么,应该是加热器仅仅负责烧水,它不能发出警报也不能显示水温;在水烧开时由警报器发出警报、显示器显示提示和水温。
事情发生的顺序应该是这样的:1. 警报器和显示器告诉热水器,它对它的温度比较感兴趣(注册)。2. 热水器知道后保留对警报器和显示器的引用。3. 热水器进行烧水这一动作,当水温超过95度时,通过对警报器和显示器的引用,自动调用警报器的MakeAlert()方法和显示器的ShowMsg()方法。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DelegateEventExample
{
///
/// 这是加热器,只负责烧水。
/// 加热器是Observer模式中的被监视对象。当水温达到95度时,会触发监视它的方法。
///
public class Heater
{
private int temperature; //水温,被监视对象。
// 第一步:声明一个委托,并规定了委托的方法的参数类型为int
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)
{
// 第五步:水温达到95度,调用所有注册对象的方法(监视者)。
BoilEvent(temperature);
}
}
}
}
}
///
/// 这是报警器
/// 报警器是Observer模式中的监视者。当水温达到95度时,报警器被触发并发出报警。
///
public class Alarm
{
// 第六步:收到水温达标的通知,发生警报
public void MakeAlert(int param)
{
Console.WriteLine("Alarm:嘀嘀嘀,水已经 {0} 度了:", param);
}
}
///
/// 这是显示器
/// 显示器是Observer模式中的监视者。当水温达到95度时,显示器被触发并显示温度。
///
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 += Display.ShowMsg;
// 第四步:开始烧水
heater.BoilWater();
}
}
}