设计模式-行为模式(Observer)

原创 2005年05月23日 16:28:00

设计模式-行为模式(Observer)

1、  定义:

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。

 

《设计模式的有趣解释-追MM》中解释:OBSERVER—想知道咱们公司最新MM情报吗?加入公司的MM情报邮件组就行了,tom负责搜集情报,他发现的新情报不用一个一个通知我们,直接发布给邮件组,我们作为订阅者(观察者)就可以及时收到情报啦?
观察者模式:观察者模式定义了一种一队多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使他们能够自动更新自己。

这是Command模式的UML图:

2、 适用性

当一个抽象模型有两个方面, 其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。

当对一个对象的改变需要同时改变其它对象, 而不知道具体有多少对象有待改变。

当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之, 你不希望这些对象是紧密耦合的。

3、模式分析

虽然Observer模式有很多变体,但该模式的基本前提包含两个角色:观察者(observer)主体(subject)(熟悉Smalltalk MVC的人将这些术语分别称为ViewModel)。在用户界面的环境中,观察者是负责向用户显示数据的对象。另一方面,主体表示从问题域中模拟的业务抽象。正如图1中所描述的一样,在观察者和主体之间存在逻辑关联。当主体对象中发生更改时,(例如,修改实例变量),观察者就会观察这种更改,并相应地更新其显示。


1 观察者和主体关系

    例如,假定我们要开发一种简单的应用程序,来跟踪全天的股票价格。在此应用程序中,我们指定一个Stock类来模拟在NASDAQ交易的各种股票。该类包含一个实例变量,它表示在全天不同时段经常波动的股价。为了向用户显示此信息,应用程序使用一个StockDisplay类向stdout(标准输出)写信息。在此应用程序中,一个Stock类实例作为主体,一个StockDisplay类实例作为观察者。随着股价在交易日中随时间发生变化,Stock实例的当前股价也会发生变化(它怎样变化并不重要)。因为StockDisplay实例正在观察Stock实例,所以在这些状态发生变化(修改股价)时,就会向用户显示这些变化。

    通过使用这种观察过程,可以在StockStockDisplay类之间划分界限。假定应用程序的要求第二天发生变化,要使用基于窗体的用户界面。要启用此新功能,只需要构造一个新类StockForm作为观察者。无论发生什么情况,Stock类都不需要进行任何修改。事实上,它甚至不知道发生此类更改。类似地,如果需求变化要求Stock类从另一个来源检索股价信息(可能是从Web服务,而不是从数据库中检索),则StockDisplay类不需要进行修改。它只是继续观察Stock就够了。

物理模型

    正如大多数解决方案一样,问题在于细节。Observer模式也不例外。虽然逻辑模型规定观察者观察主体;但在实现这种模式时,这实际上是一个名称误用。更准确地说,观察者向主体注册,表明它观察主体的意愿。在某种状态发生变化时,主体向观察者通知这种变化情况。当观察者不再希望观察主体时,观察者向主体撤消注册。这些步骤分别称为观察者注册通知撤消注册

    大多数框架通过回调来实现注册和通知。图234中所示的UML序列图模拟这种方法通常使用的对象和方法调用。对于不熟悉序列图的人来说,最上面的矩形框表示对象,而箭头表示方法调用。


2 观察者注册

    2描述了注册序列。观察者对主体调用Register方法,以将其自身作为参数传递。在主体收到此引用后,它必须将其存储起来,以便在将来某个时间状态发生变化时通知观察者。大多数观察者实现并非将观察者引用直接存储在实例变量中,而是将此任务委托给一个单独的对象(通常为一个容器)。使用容器来存储观察者实例可提供非常大的好处,我们将对它进行简要介绍。


3 观察者通知

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


4 观察者撤消注册

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

    回到我们的股票应用程序,让我们分析一下注册和通知过程所产生的影响。在应用程序启动过程中,一个StockDisplay类实例注册到Stock实例中,并将其自身作为参数传递到Register方法。Stock实例(在容器中)保存对StockDisplay实例的引用。当股价属性发生变化时,Stock实例通过调用Notify方法向StockDisplay通知所发生的变化。在应用程序关闭时,StockDisplay实例使用以下方法撤消注册Stock实例:调用UnRegister方法,终止两个实例之间的关系。

    请注意利用容器(而不是使用实例变量)来存储观察者引用有什么优点。假定除当前用户接口StockDisplay外,我们还需要绘制股价在交易日内变化的实时图形。为此,我们创建了一个名为StockGraph的新类,它绘制股价(y轴)和当天时间(x轴)的图形。在应用程序启动时,它同时在Stock实例中注册StockDisplayStockGraph类的实例。因为主体在容器(与实例变量相对)中存储观察者,所以这不会出现问题。当股价发生变化时,Stock实例向其容器中的两个观察者实例通知所发生的状态变化。正如我们所看到的一样,使用容器可提供更大的灵活性,即每个主体可支持多个观察者。这使主体有可能向无数多个观察者通知所发生的状态变化,而不是只通知一个观察者

    虽然不是强制要求,但很多框架为观察者和主体提供了一组要实现的接口。正如下面的C#代码示例所示,IObserver接口公开一种公共方法Notify。此接口是由所有要用作观察者的类实现的。IObservable接口(是由所有要用作主体的类实现的)公开两种方法RegisterUnRegister。这些接口通常采用抽象虚拟类或真实接口的形式(如果实现语言支持此类构造的话)。利用这些接口有助于减少观察者和主体之间的耦合关系。与观察者和主体类之间的紧密耦合关系不同,IObserverIObservable接口允许执行独立于实现的操作。通过对接口的分析,您将注意到键入的所有方法针对的是接口类型(与具体类相对)。这种方法将接口编程模型的优点扩展到Observer模式。

主体:

       public class Stock extends Observable {

      

              public void change() {

                     this.setChanged();

                     this.notifyObservers("ok");

              }

}

观察者:

       public class StockDisplay implements Observer {

              public void update(Observable o, Object arg) {

                     System.out.println("ObserverObj:" + arg);

              }

}

调用程序:

       public static void main(String[] args) {

              Stock sub = new Stock ();

              StockDisplay ob = new StockDisplay ();

              sub.addObserver(ob);

              sub.change();

       }

这样主体Stock和观察者StockDisplay之间没有任何耦合关系,只是在调用程序中,将StockDisplay注册到主体Stock中,最后通过回调(Callback)实现了消息通知。

参考:http://editblog.csdn.net/msdncolumn/archive/2004/12/30/1105.aspx

Observer观察者设计模式(对象行为型)

意图: 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新适用性 在以下任一情况下可以使用观察者模式: • 当一个抽象模型有两个方面, 其中一...

JAVA设计模式(15) —<行为型>观察者模式(Observer)

1 定义: 观察者模式(Observer Pattern),也叫做发布订阅模式(Publish / subscribe) Define a one-to-many dependency betwee...

【设计模式】行为模式之Observer观察者

Observer观察者是一种对象行为型设计模式,目的是定义对象间的一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。在进行系统设计时,通常会将一个系统分割成一系列相...
  • iEearth
  • iEearth
  • 2016年09月02日 07:15
  • 357

设计模式(行为型)之观察者模式(Observer Pattern)

观察者模式用于建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应作出反应。在观察者模式中,发生改变的对象称为观察目标,而被通知的对象称为观察者,一个观察目标可以对应...

"围观"设计模式(19)--行为型之观察者模式(Observer Pattern)

观察者模式是软件设计模式的一种。在此种模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实时事件处理系...

设计模式--观察者模式Observer(行为性)

观察者模式 Observer 设计模式

设计模式 ( 十六 ) 观察者模式Observer(对象行为型)

设计模式 ( 十五 ) 观察者模式Observer(对象行为型)    1.概述 一些面向对象的编程方式,提供了一种构建对象间复杂网络互连的能力。当对象们连接在一起时,它们就可以相互提供...

设计模式(4)-行为型-观察者模式(Observer)

> 意图: - 有时也被称作发布/订阅模式。 - 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。 > 个人理解: - 首先,他们之...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:设计模式-行为模式(Observer)
举报原因:
原因补充:

(最多只允许输入30个字)