1、什么是观察者模式
事件的触发和反应是一种观察者模式,主要由两部分组成:
被观察者:相当于事件发布者(定义事件,触发事件),其中有一些属性来被其它对象所监视。
观察者:相当于事件的订阅者(事件对应具体方法实现),它会观察被监视对象的某些属性,当这些属性发生变化时,会触发观察者做出对应的反应。观察者一般可以有多个。
被观察对象只管触发事件,而不管是否有人订阅了该事件。
被观察者的状态发生了改变之后需要通知观察者做出相应的动作,比如在游戏中当我们点击了一个开始按钮,就需要加载音乐、场景等,这里的按钮就是被观察者,场景和音乐管理器就是观察者。
例题1:猫大叫,老鼠开始逃跑,主人醒来,宝宝也醒来了并且哭了起来
思路:这题猫是被观察者,老鼠、主人、宝宝都是观察者
我们需要在猫类里面定义好事件,其他类完成事件对应具体方法实现
namespace ConsoleApp1
{
public delegate void DEL();
internal class Program
{
static void Main(string[] args)
{
Cat cat = new Cat();
Mouse mouse = new Mouse();
People people = new People();
Baby baby = new Baby();
cat.del += mouse.Run;
cat.del += people.Runww;
cat.del += baby.Runmm;
cat.Awake();
Console.ReadKey();
}
}
/// <summary>
/// 猫
/// </summary>
class Cat
{
public event DEL del;
public void Awake()
{
Console.WriteLine("猫醒了,大叫了一声");
del();
}
}
class Mouse
{
public void Run()
{
Console.WriteLine("老鼠开始逃跑");
}
}
class People
{
public void Runww()
{
Console.WriteLine("主人醒了");
}
}
class Baby
{
public void Runmm()
{
Console.WriteLine("宝宝哭了");
}
}
}
例题2
加热水的加热器,时刻显示水温的显示器,当水温达到90度时的报警器。这三者来共同组成该程序,代码如下:
namespace 事件详解2
{
class Program
{
static void Main(string[] args)
{
Heater heater = new Heater();
Alarm alarm = new Alarm();
Display display = new Display();
heater.curTemperature += alarm.MakeAlarm; //将报警函数注册到事件上
heater.curTemperature += display.ShowTemperature; //将显示温度函数注册到事件上
heater.Heating();//开始加热
}
}
public delegate void SendTemperatureEvent(int num);
/// <summary>
/// 加热器:负责加热。相当于事件发布者,用来发布当前水温。
/// </summary>
class Heater
{
public event SendTemperatureEvent curTemperature;
private int temperature; //水温
private int maxTemp = 100;
public void Heating()
{
//水温从85度开始
for (int i = 85; i <= maxTemp; ++i)
{
temperature = i;
if (curTemperature != null)
{
curTemperature(temperature); //触发事件
}
Thread.Sleep(1000); //线程睡眠1秒
}
Console.WriteLine("现在水温 100℃ !!!");
Console.ReadKey();
}
}
/// <summary>
/// 报警器:当水温达到一定的值时,进行报警
/// </summary>
class Alarm
{
//订阅者:从加热器那里订阅水温,当水温达到一定值,就开始报警。
public void MakeAlarm(int temperature)
{
if (temperature > 90)
{
Console.WriteLine($"现在水温 {temperature}");
}
}
}
/// <summary>
/// 显示器:显示水温值
/// </summary>
class Display
{
//订阅者:从加热器那里订阅水温,并进行显示。
public void ShowTemperature(int temperature)
{
Console.WriteLine($"水温 :{temperature}");
}
}
}