在认识委托和事件之后,可以进阶一下一些设计模式了,这篇主要描述的是关于事件处理机制中的基础,一种叫做“观察者模式”的设计模式:ObServe设计模式,这种设计模式是针对面向对象语言,对象间的一种一对多的依赖关系,以便于主干的状态发生变化时,其他依赖于主干的依赖象也会受到影响,自动告知并更新;这种设计模式也是一种松耦合的设计模式;
再深入的描述一下Observe模式中主要存在那些成员,之间有什么样的联系;
这之间含有两个成员:一个是Subject(监视对象),另外一个是Observe(监视者);Subject,它包含着其他对象所感兴趣的内容,Observe监视着Subject,当Subject中某件事情发生的时候,会告诉Observe,Observe则会采取相应的行动。
TestDemo:
现在举个例子,显卡是大多电脑的一件核心成员,主要对电脑的图像进行加工处理;一张高端的显卡,假设只有三个部分组成,显示屏,主板机身,警报器;
我们已经大致知道了一张电脑显卡的具体组成成员了,现在模拟一张显卡正在被使用的场景:我的电脑多正在玩着大型的单机游戏,并且我不断的在后台打开更多对图像处理要求十分高的程序进程;随着进程越来越多,显卡的温度也随之上升,显示器随着实际温度变化而变化,我们知道,一张显卡长期处于一种高温的情况下工作,是会有所损坏的,所以警报器的作用就是,当前如果超过95°的情况下发出警报; 显示器是一个实时的温度显示;
在本事例中,结合文字描述,我们大概总结罗列一下事件发生的顺序:、
- 显卡的警报器 和 显示屏告诉机身,他们对机身的温度感兴趣
- 机身得知后保留对显示器和警报器的引用
- 运行电脑时,显卡开始工作,当图像处理越来越复杂,温度随之上升,温度的变化会调用“显示器” 与“警报器”来同步呈现当前机身温度的状况;
由上述的描述可以发现:这一系列的操作就是一个事件的过程,在写测试代码之前,我们再了解一下什么是委托事件:
首先我们知道委托可以将方法当成入参去代入,又可以注册函数,我们声明委托的目的就是要它暴露在类的客户端进行方法的注册,所以这里有个关键点,我们到底是定义成私有成员private呢?还是定义成公开成员publice呢?定义成private的话,客户端根本不可见,可以说是没什么作用,如果定成Public 的话,又破坏了其封装性,可以进行随意的赋值;所以这种情况,就是事件(Event)出场的时候了;
委托在程序运行时会变成一个类,如果使用了event关键字,又会生成一个类,将前面的类封装起来,这样的作用就是不管你声明为公有的还是保护的类别 ,它在类的delegate它总时private的;
接下来就是通过代码,结合上面的描述,使用事件处理的方式结合Observe来看一看;
首先我们要明确目前所有得条件:1.显卡,显卡上的温度显示器,显卡高温警告器三个硬件上的东西,还有一个会变化的内容,显卡的温度会随着电脑运行而提高温度;好,既然有了概念,就可以写实现了:
用一个C#控制台应用程序来展示这一段代码:
一:定义一个名为GPU的class;里面包含定义了一个int GpuTemperature来显示GPU的温度,声明了一个委托和事件,RunTime()方法主要是GPU在运行时,当GpuTemperature温度到达95°以上的时候,调用注册对象的方法(BoilEvent?.Invoke(GpuTemperature))
二:定义警报器,模拟真实的警报器,在控制台输出文字提醒:
三:定义显示器,模拟真实的显卡显示器,在控制台输出文字提醒;
当我们前期的准备工作已经完成了,现在时最后一步,就是在控制台应用程序中输出它,从文字的变化去结合我们更好的理解Observe + 事件的这种设计模式:
我们在static void Main()中输出它:
GPU working = new GPU();
Alertor alertor = new Alertor();
working.BoilEvent += alertor.MakeAlertor; //注册方法
working.BoilEvent += DisplayScreen.ShowMsg; //注册静态方法
working.RunTime();//显卡运行中,会自动调用注册过对象的方法
Console.ReadKey();//停留在界面,当下次按下按键时关闭控制台应用程序
然后我们最终看到的结果:
从结果看,我们已经理解这种设计模式的好处了,不仅仅试代码规范这么简单,同时也使程序有了更大的灵活性;