.Net中使用事件和委托实现Observer模式(一)

来源:互联网 发布:人工智能会议参会人员 编辑:程序博客网 时间:2024/05/16 18:14

最近一个项目中使用C#开发windows应用程序,其中有多处地方需要实现这样的功能:某个属性或者数据变化后,须同步更新某个或多个界面上的显示效果。从设计模式的角度来看,这属于典型的Observer模式。

Observer模式的基本前提应包含两个角色:观察者(observer)和主体(subject)(MVC中叫View和Model)。实际的应用中,观察者多是用户界面上的元素,负责向显示数据信息或展现数据的变化状态。而主体,一般是具体的业务对象。在观察者和主体之间存在逻辑关联。当主体对象中发生更改时,会通知观察者这种更改,后者则会更新显示。 

Observer模式的介绍网上有很多,以下摘了一段有关Observer模式的文章段落,基本把原理讲的很清楚了:

---------------------------------------------------------------------------------------------------------------------

正如大多数解决方案一样,问题在于细节。Observer模式也不例外。虽然逻辑模型规定观察者观察主体;但在实现这种模式时,这实际上是一个名称误用。更准确地说,观察者向主体注册,表明它观察主体的意愿。在某种状态发生变化时,主体向观察者通知这种变化情况。当观察者不再希望观察主体时,观察者向主体撤消注册。这些步骤分别称为观察者注册、通知和撤消注册。
大多数框架通过回调来实现注册和通知。图2、3和4中所示的UML序列图模拟这种方法通常使用的对象和方法调用。对于不熟悉序列图的人来说,最上面的矩形框表示对象,而箭头表示方法调用。
图2
图2描述了注册序列。观察者对主体调用Register方法,以将其自身作为参数传递。在主体收到此引用后,它必须将其存储起来,以便在将来某个时间状态发生变化时通知观察者。大多数观察者实现并非将观察者引用直接存储在实例变量中,而是将此任务委托给一个单独的对象(通常为一个容器)。使用容器来存储观察者实例可提供非常大的好处,我们将对它进行简要介绍。

图3
图3突出显示了通知序列。当状态发生变化时(AskPriceChanged),主体通过调用Get观察者s方法来检索容器中的所有观察者。主体然后枚举检索的观察者,并调用Notify方法以通知观察者所发生的状态变化。

图4

图4显示撤消注册序列。此序列是在观察者不再需要观察主体时执行的。观察者调用UnRegister方法,并将其自身作为参数进行传递。然后,主体对容器调用Remove方法以结束观察过程。
------<转帖结束>--------------------------------------------------------------------------------------------------------------

 

.NET框架中并没有提供Observer的框架,类似应用场景的处理,Microsoft则提供了另一种解决方案--委托和事件处理机制。相比传统的Observer框架而言,更加强大和灵活。有关委托和事件处理介绍的文章也很多,不再详述。 

这里需要明确几个概念:

委托:可理解为函数的指针,委托的实例保存对(实例或类)方法的引用。 

事件:是在类上声明的特殊构造,可在运行时发布被关注对象的状态变化。委托是在运行时注册到特定事件中的。在引发事件时,将调用所有注册到该事件上的委托,从而运行该委托所指向的方法。
Observer中的主体:对应于声明事件的类。与传统的Observer模式框架不同的是:主体类不需要实现给定接口或扩展基类,仅需要公开一个事件即可。

Observer中的观察者:对应于声明事件委托方法的类,与传统Observer模式框架不同的是观察者不需要实现IObserver接口和将其自身注册到主体中,仅需创建特定的(与主体事件委托签名一致)委托实例,并将此委托实例注册到主体事件中。在创建此委托实例的过程中,观察者将传递该主体向委托通知的方法(实例或静态)名称。在将委托绑定到方法后,可以将其注册到主体的事件中。类似地,也可以从事件中撤消注册此委托。主体通过调用事件向观察者提供通知。 

相关的原理基本就是这些,下一部分具体看看如何通过C#代码来实现。

原创粉丝点击