(1)Subject:就是“被观察者”的角色,它将所有观察者对象引用保存在一个集合中,每个“观察者”都可以有任意数量的 “观察者”,而自身提供一个接口,可以增加和删除观察者对象。
(2)Observer:抽象“观察者”,它定义了一个更新接口,使得在“被观察者”状态改变时通知自己,可及时更新。
(3)ConcreteObserver: 具体的”观察者“,该角色实现抽象“观察者”角色所定义的更新接口,以便在“被观察者”状态改变时更新自身状态。
二. “观察者模式”实现
以上的理论大家并不陌生,可是理论部分知晓的再熟悉,未融入到实际应用中也是枉然!还是回到“应用宝软件下载”实际例子中,注意上述简介中的UML图分析其实大致已将需要实现的步骤给出来了,以下:
1. “被观察者” Subject 对象
首先,我们需要一个“下载管理器”DownloadManager,也就是观察者模式中的“被观察者”。(注意:一般这里的“被观察者”数量唯一!)一般像这种全局的管理器,需要将它设置成 “单例模式”,在这里使用 饿汉形式。
再次回顾逻辑,如上图所示,可得知在具体页面点击的“下载”,进度可同时在详细页面和首页中展示,相反亦是。从设计模式的角度来讲,这种就是“观察者设计模式”。也就是说 下载 的逻辑只在一处去做,但是有多个界面在 监听 其进度。
观察者设计模式有两个元素,一个叫做“被观察者”,另一个是“观察者”。一般而言 被观察者 只有一个,而观察者的数量却不止一个。举个栗子:在大街上,一个老太太摔倒了,路上行人不免开始围观,而些许路人要事在身,匆匆看一眼便走了,有些闲人驻足观望。这时,我们的老太太便成为了 “被观察者”,这数量不定的路人就是 “观察者”。 而 “观察者”中有两个方法: 注册观察者、注销观察者。这就是“观察者”的设计模式。
4. 通知状态变化方法(回调 观察者 接口) !!!
可是现在这些 观察者 如何收到变化呢然就需要 被观察者 通知给大家。这时还是回到我上面举得例子 (我们不要考虑天底下所有的老太太摔跤都是为了讹钱),老太太在地上缓了一会,深知大家都以为她是讹钱的,自己慢慢爬了起来,告诉众人没事没事,都散了吧,这时路人了解了情况,开始散开各行其事去了。而这里就是 被观察者通知给观察者,观察者做出反应 的事例。
所以,一开始定义的 下载管理器DownloadManager类就是 被观察者,谁需要去观察它呢页和某个App的详情页面会去观察它!从它这里拿到 下载的进度,对其显示。 此时,该观察者也就有责任去通知大家 状态发生变化了。在DownloadManager类中需要再增加两个方法(观察者接口中是两个方法),来通知该状态的变化。
(1)通知下载状态发生变化:状态改变时,对所有的观察者(mObservers 集合)遍历,调用接口中对应状态改变的方法。(这里是onDownloadStateChanged)
(2)通知下载进度发生变化:如上所示。
三. 总结
1.逻辑总结
暂且回顾以上4点,也就是DownloadManager类:
(1)“被观察者” Subject 对象
(2) 声明“观察者”的接口
(3)注册、注销”观察者“方法
(4)通知状态变化方法(回调 “观察者” 接口)
以上4点都是在DownloadManager,也就是被观察者中的逻辑,把逻辑整体串一遍:我们的观察者只会有一个,首先在DownloadManager中给 被观察者 限制为单例模式;再声明 观察者 接口(定义好观察者观察的状态),维护一系列的 观察者集合,再加两个注册和注销观察者的方法,算是对 观察者 的管理;之后当观察者接口中 所关注的状态有所改变时,被观察者中有义务立刻通知,再加两个方法,即在新增方法中调用 观察者接口中对应状态改变的 接口。
2. 观察者模式 与 回调
总体就是,一旦 被观察者的状态改变后,观察者中的方法就会被调用。理解之后,你会发现,观察者模式 就是 在 回调!先声明接口,再声明方法,把监听传过来,只不过我们这里的监听不止一个,而是用集合 维护了 一堆监听,然后再适当的时机马上去通知回调。两者有异曲同工之妙,非要说区别的话,”回调“中只有一个监听者,而这里的“观察者设计模式”中有许多个监听者。
以上,这里只是把此功能 的 核心骨架 抽取出来讲解,具体还有 “观察者接口”实现的部分等等,但是核心思想模式的理解是重要的一步!
希望对你们有帮助:)
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!