观察者模式

    xiaoxiao2021-04-12  37

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


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

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

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

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

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

    没有加入订阅组的用户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中的普及程度,实质上这也可以看作一种针对“接口”的编程。

    转载请注明原文地址: https://ju.6miu.com/read-668094.html

    最新回复(0)