Pulpcode

捕获,搅碎,拼接,吞咽

0%

c#事件处理之观察者模式

Introduction

c#中事件处理的第二部分写观察者模式。

观察者模式是一种常用的设计模式,主要用在事件通知上。

观察者模式中,主要分为两种类,主题类(subject)和观察者类(observe)。两者是一对多的关系,也就是一个主题类上注册了多个观察者。当主题类发生变化时,能够主动将变化推送给每个观察者。

模型结构

首先,如果我们完全不谈观察者模式中的推送数据,调用方法的模块。仅仅谈论对象建模,观察者模式本身其实在定义对象之间的一对多的关系。其中主题类在维护一个观察者类的容器。注册和注销都是在维护这个容器。

这一点很重要,维护容器,使得订阅和取消订阅都变得非常简单。

定义接口

主题类需要实现的接口:

1
2
3
4
5
6
interface ISubject
{
void Attach(Observer);
void Detach(Observer);
void Notify();
}

其中,Attach用来注册监听者,Detach用来注销监听者。Notify用来通知每一个监听者。

Attach的实现基本就是向观察者容器中添加一个观察者。

Detach的实现基本就是从观察者容器中删除一个观察者。

Notify的实现基本就是调用每一个观察者实现接口。

观察者类需要实现的接口:

1
2
3
4
interface IObserver
{
void Update();
}

Update就是每一个观察者在得到更新数据后的具体操作。

要注意的是,这里把Update接口写的比较简单,正常情况下,Update应该是有两个参数的,Object SenderEventArgs e,其中Sender表示主题对象,e表示主题传来的其它参数。

java和c#中的事件实例

这里首先要说明,上面对观察者模式的介绍,是为了表达Observer与Subject是如何处理两者之间的依赖关系的。具体实现是不是用容器维护,是不是要实现接口就不一定了。比如c#使用委托来完成事件处理的。

但是无论是什么实现,这种思想基本都是一样的。

java中,比如一个button就算是一个主题类,为button添加的ActionListener,就算是为主题类注册的观察者,当button的事件触发时,就会通知到每一个ActionListener(事件监听器)上,这就相当于主题类发生变化的时候,会通知注册到它的观察者上。

1
2
JButton button = new JButton("Should I do it?");
button.addActionListener(new xxxListener());

c#中的写法,要比java有趣一些。

它不是要实现某个Listener接口,而是要写一个参数符合要求的处理函数。因为c#是使用委托实现的。

它使用+=运算符,来为某个事件注册监听器

它使用-=运算符,来为某个事件注销监听器

比如下面代码就监听了Timer的Elapsed事件。

1
2
var pollTimer = new Timer(100);
pollTimer.Elapsed += new ElapsedEventHandler();