观察者模式

来源:互联网 发布:浙江大学会计专硕 知乎 编辑:程序博客网 时间:2024/06/06 12:38

这篇博客主要总结一下观察者模式。


观察者模式应该算是众多设计模式中,
应用比较广,同时也比较好理解的模式了。

因此这里直接给出它的定义:
观察者模式定义了对象之间的一对多依赖,
这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。

观察者模式的思想基本上可以用上图来说明。

有状态的对象将作为消息发布者,
负责将状态变化的信息通知给观察者们。

如图所示:
加入了订阅组的用户就是消息发布者的观察者,
它们会在必要时收到通知消息。

没有加入订阅组的用户4,不会收到通知信息。

用户可以自由的加入和离开订阅组。

这个过程,就像你在新闻APP中订阅某个专题一样。
如果你订阅了该专题,
那么有该专题的新闻出现时,就会主动推送给你。
如果某天你对该专题没兴趣了,
就可以取消订阅,此时就不会收到任何推送新闻了。


接下来,我们看看观察者模式相关的类图:

如上图所示,主题只需要知道观察者实现了Observer接口,而不需要知道其它的细节。
因此实际的主题对象,例如图中的ConcreteSubject对象,只需要将观察者当作Observer保存。

同理,观察者也不需要知道主题的实现细节,只需要知道主题实现了Subject接口。
通过Subject中的registerObserver接口,观察者可以将自己注册到主题;
通过removeObserver接口,观察者可以取消对主题的关注。

当主题发现状态改变时,就可以调用notifyObserver方法,调用保存的所有观察者的update函数。

此外,主题对象还可以提供getState和setState方法,供其它对象主动获取或设置主题的状态。

通过上图可以看出,整个观察者模式提供了一种松耦合的设计。
主题和观察者之间可以交互,但不需要清楚彼此的细节。
只要遵循它们之间定义的接口,那么改变主题或观察者其中一方,并不会影响另一方。


最后,我们来看看Android源码中使用观察者模式的例子。

Android中使用观察者模式的地方很多,此处我们以RIL的通知框架为例。

如图所示,RIL接收modem上报的信息,作为整个通知框架的消息发布者,即主题。
RIL继承BaseCommands类,后者实现了CommandsInterface接口。

CommandsInterface接口中定义了许多注册、反注册函数,这里以RadioState相关的函数为例。
ServiceStateTracker作为观察者,需要将自己的Handler等参数注册到主题中。

主题将利用利用这些参数构造出Registrant对象,
并保存到BaseCommands中的mRadioStateChangedRegistrants中。

当RadioState发生变化时,BaseCommands就会通知mRadioStateChangedRegistrants中的所有Registrant。
Registrant就会利用自身的Handler发送消息给实际的观察者ServiceStateTracker。

RIL通知框架的类图与上文提到的观察者模式类图基本一致,
唯一的区别是观察者并没有继承接口对象,而是将Handler注册到主题中。
考虑到Handler在Android中的普及程度,实质上这也可以看作一种针对“接口”的编程。

0 0
原创粉丝点击