设计模式:Observer模式

在做面向对象的软件开发过程中,有时候会碰到这样一种情况:某一个对象的变化会导致很多个对象同时发生变化,必须是及时的变化,而且受影响的对象也是未知的。Observer模式正好是解决这类问题的拿手方案。

 

 

定义
观察者模式定义了对象间的一种一对多依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。
The Observer Pattern defines a one-to-many dependency between objects so that when one object changes state, all of its dependents are notified and updated automatically.

 

 

图解

下面就用类图来解说一下Observer模式的主要思想。使用这个模式主要有两种对象,一个是被观察的对象,也就是它的变化会导致其他对象发生变化的那个对象;另外一种就是不定数目的观察者对象。被观察者提供了注册观察者的方法addObserver(),移除观察者的方法removeObserver()和通知观察者的方法notifyObserver()。在程序运行过程中,可以随时为被观察者增加观察者,当被观察者发生变化之后,就会通知所有的观察者,并调用观察者的方法update()来完成相应的更新。由于每个观察者对象所对应的变化时不相同的,所以要有各个观察者自己完成更新。

 

图一

Observer设计模式

 

 

推/拉模式

对于Observer模式来讲,关键是当被对象发生变化后,观察者应该如何变化。根据对数据的需求不同,可以分成两种模式,“推数据”模式和“拉数据”模式。

 

“推数据”模式是指被观察者直接把变化的数据通过参数的方式传递给观察者,如图一中Observer的方法update()的参数obj,当然这个参数的类型可以任意的改变成需要的类型。这种模式比较适合于那种所有的观察者需要的都是同样的数据的情况。

这种模式,只需要把图一中Observer的方法update()的参数类型变成需要的类型即可。

 

“拉数据“模式是指被观察者通知观察者数据发生了变化,然后观察者从被观察者处把需要的数据拉过来。这种模式适合于观察者有多种类型,并且各种类型所需要的数据也是不一样的情况。

这种模式首先需要被观察者的父类或者接口提供获取某些数据的方法,另外观察者也要能获得对被观察者的引用。下面两幅图是对这种模式的一些使用方法。

图二

Observer设计模式

图三

Observer设计模式

 

 

JDK中自带的Observer模式的使用

以上的图解是基本的形式,对于任何有面向对象的编程语言都是通用的。

而JDK中已经为我们提供了方便使用Observer模式的类和接口,Observable类和Observer接口。只要让我们的被观察者类继承Observable类,观察者实现Observer接口,再添加一些简单的代码,就完全可以实现Observer模式了。

 

图四中,Observer接口和Observable类就是JDK中的提供的,它们自带的方法如图所示。

其中,ConcreateObserver类必须实现update方法,这是指当观察者发生变化后,被观察者要发生的变化。

而ConcreateObservable类必须要有变更的方法如图中的changeSomething方法,当被观察者发生变化时,应该先调用setChanged方法,表明自己发生变化了,然后调用两个notifyObservers方法中的一个去通知被观察者。

图四

Observer设计模式

 

JDK中自带的Observer模式的不足

JDK中自带了Observable类和Observer接口,确实方便了我们对Observer模式的使用。不过,由于这里提供的被观察者是类而不是接口,而Java中又只支持单一继承,所以如果你的类已经有父类并且不能变更为接口的话,那可能就只有自己实现Observer模式了。

 

网上看到有朋友提出一种解决方案,就是使用adapter模式来解决这个问题。

具体来讲是,假如你的观察者以前继承了类SrcObject,那么变更它的继承者为Observable,然后增加一个引用SrcObject类的私有属性,然后所有的相关方法都调用这个私有属性的方法。

这种方法勉强可以解决上面提出的问题,但是这只是在SrcObject类是一个一般类并且没有使用其他模式的情况下。比如说,如果SrcObject使用了template method模式的话,这个方案就不灵了。

 

适用场合

1. 对一个对象状态的更新,需要其他对象同步更新,而且其他对象的数量动态可变。

2. 对象仅需要将自己的更新通知给其他对象而不需要知道其他对象的细节。

 

从以上的介绍中,我们也可以看出以下一些特点。

1. Observer和Subject之间是松耦合的,二者可以独立的变化。

2. 被观察者无须知道具体有哪些观察者,观察者可以动态的添加,注销。

3. 观察者数量过多的话,有可能会有性能问题存在。(毕竟是遍历)

 

 

在我们的软件开发过程中,Observer模式是会被经常用到的一个设计模式,比如说,发布者与订阅者,有很多网站都定期出版自己的电子杂志,而用户可以在网站上随时的订阅或者取消订阅;写UI程序的时候,对工具栏中的button变灰不变灰的控制;有些对象需要接受数目不定的对象作为参数,但是是使用完毕后要全部进行释放;。。

善加利用会给我们的设计带来很大的便利。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值