Android之“观察者模式”解析及实际应用:"应用宝"软件下载中 进度条同步更新

本文通过一个具体的案例——应用宝软件下载功能,详细介绍了观察者模式的设计思路与实现过程。包括被观察者、观察者接口的定义,以及如何通过注册和注销观察者来实现状态和进度的同步更新。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这里写图片描述

这是模仿“应用宝”的demo,这里提取出一个功能来讲解:在首页中,选择一个App点进去,进入到详细介绍页面,点击页面最下方下载按钮,进度条变化开始下载。再次回到首页,首页中的进度条 与 详细页面的进度条 同步更新 !相信熟悉设计模式的人已经想到这就是 “观察者模式”

由于关于这个理论方面的博客实在是太多了,此篇将重点放在应用上,但下面还是简单介绍一下此模式。




一 .“观察者模式”简介

(此模式简介部分来源于书籍《Android源码涉及模式解析与实战》)

1. 定义
观察者模式:定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新

2.意义
此模式最重要的作用就是 解耦!将被观察者和观察者解耦,使得它们之间的依赖性更小。


3. UML图

这里写图片描述

(1)Subject就是“被观察者”的角色,它将所有观察者对象引用保存在一个集合中,每个“观察者”都可以有任意数量的 “观察者”,而自身提供一个接口,可以增加和删除观察者对象。
(2)Observer抽象“观察者”,它定义了一个更新接口,使得在“被观察者”状态改变时通知自己,可及时更新
(3)ConcreteObserver具体的”观察者“,该角色实现抽象“观察者”角色所定义的更新接口,以便在“被观察者”状态改变时更新自身状态。







二. “观察者模式”实现

以上的理论大家并不陌生,可是理论部分知晓的再熟悉,未融入到实际应用中也是枉然!还是回到“应用宝软件下载”实际例子中,注意上述简介中的UML图分析其实大致已将需要实现的步骤给出来了,以下:



1. “被观察者” Subject 对象

首先,我们需要一个“下载管理器”DownloadManager,也就是观察者模式中的“被观察者”。(注意:一般这里的“被观察者”数量唯一!)一般像这种全局的管理器,需要将它设置成 “单例模式”,在这里使用 饿汉形式。

/**
 * 下载管理器 [观察者模式]
 *  DownloadManager: 被观察者, 有责任通知所有观察者状态和进度发生变化
 *
 * Created by gym on 2016/9/20.
 */

public class DownloadManager {
    //单例模式---饿汉
    private static DownloadManager mDM = new DownloadManager();

    private DownloadManager(){};

    public static DownloadManager getInstance(){
        return mDM;
    }



这里写图片描述

再次回顾逻辑,如上图所示,可得知在具体页面点击的“下载”,进度可同时在详细页面和首页中展示,相反亦是。从设计模式的角度来讲,这种就是观察者设计模式”。也就是说 下载 的逻辑只在一处去做,但是有多个界面在 监听 其进度。


观察者设计模式有两个元素,一个叫做“被观察者”,另一个是“观察者”。一般而言 被观察者 只有一个,而观察者的数量却不止一个。举个栗子:在大街上,一个老太太摔倒了,路上行人不免开始围观,而些许路人要事在身,匆匆看一眼便走了,有些闲人驻足观望。这时,我们的老太太便成为了 “被观察者”,这数量不定的路人就是 “观察者”。 而 “观察者”中有两个方法: 注册观察者、注销观察者。这就是“观察者”的设计模式。
这里写图片描述


2. 声明观察者的接口

首先我们需要声明一个 “观察者”,这里可以用一个 接口 来表示,在例子中,路人观察者观察的是老太太伤势如何等等。 回到实际逻辑来,这里的观察者 需要观察什么?也就是说接口中需要定义什么方法? 下载状态的变化下载进度的变化

    /**
     * 1.声明观察者的接口
     */
    public interface DownloadObserver{
        //下载状态发生变化
        public void onDownloadStateChanged(DownloadInfo info);
        //下载进度发生变化
        public void onDownloadProgressChanged(DownloadInfo info);

    }



3.注册、注销观察者 方法

这里声明完观察者的接口后,还要额外写两个方法:之前提到的 注册和注销观察者 方法。而所谓注册和注销 其实就是 增加和减少 一个观察者罢了,所以在这里我们维护一个观察者的集合,对集合进行操作 就是 注册和注销观察者方法的本质。
(1). 注册观察者:参数需要将要注册的观察者传进来,并且做判断:该观察者是否为空 且 集合中是否已经包含,再向集合中增加观察者。
(2). 注销观察者:参数也需要将注销的观察者传进来,判断 该观察者不为空 且 集合确实包含它,才向集合中移除该观察者。

   //4.观察者集合
    private ArrayList<DownloadObserver> mObservers = new ArrayList<DownloadObserver>();

    //2.注册观察者
    public void registerObserver(DownloadObserver observer){
        if(observer!= null && mObservers.contains(observer)){
            mObservers.add(observer);
        }
    }

    //3.注销观察者
    public void unregisterObserver(DownloadObserver observer){
        if(observer!= null && mObservers.contains(observer)){
            mObservers.remove(observer);
        }
    }



4. 通知状态变化方法(回调 观察者 接口) !!!

可是现在这些 观察者 如何收到变化呢?当然就需要 被观察者 通知给大家。这时还是回到我上面举得例子 (我们不要考虑天底下所有的老太太摔跤都是为了讹钱),老太太在地上缓了一会,深知大家都以为她是讹钱的,自己慢慢爬了起来,告诉众人没事没事,都散了吧,这时路人了解了情况,开始散开各行其事去了。而这里就是 被观察者通知给观察者观察者做出反应 的事例。

所以,一开始定义的 下载管理器DownloadManager类就是 被观察者,谁需要去观察它呢?首页和某个App的详情页面会去观察它!从它这里拿到 下载的进度,对其显示。 此时,该观察者也就有责任去通知大家 状态发生变化了。在DownloadManager类中需要再增加两个方法(观察者接口中是两个方法),来通知该状态的变化。
(1)通知下载状态发生变化:状态改变时,对所有的观察者(mObservers 集合)遍历,调用接口中对应状态改变的方法。(这里是onDownloadStateChanged)
(2)通知下载进度发生变化:如上所示。

    // 5.通知下载状态发生变化
    public synchronized void notifyDownloadStateChanged(DownloadInfo info) {
        for (DownloadObserver observer : mObservers) {
            observer.onDownloadStateChanged(info);
        }
    }

    // 6.通知下载进度发生变化
    public synchronized void notifyDownloadProgressChanged(DownloadInfo info) {
        for (DownloadObserver observer : mObservers) {
            observer.onDownloadProgressChanged(info);
        }
    }



三. 总结


1.逻辑总结

暂且回顾以上4点,也就是DownloadManager类:
(1)“被观察者” Subject 对象
(2) 声明“观察者”的接口
(3)注册、注销”观察者“方法
(4)通知状态变化方法(回调 “观察者” 接口)

以上4点都是在DownloadManager,也就是被观察者中的逻辑,把逻辑整体串一遍:我们的观察者只会有一个,首先在DownloadManager中给 被观察者 限制为单例模式;再声明 观察者 接口(定义好观察者观察的状态),维护一系列的 观察者集合,再加两个注册和注销观察者的方法,算是对 观察者 的管理;之后当观察者接口中 所关注的状态有所改变时,被观察者中有义务立刻通知,再加两个方法,即在新增方法中调用 观察者接口中对应状态改变的 接口。



2. 观察者模式 与 回调
总体就是,一旦 被观察者的状态改变后,观察者中的方法就会被调用。理解之后,你会发现,观察者模式 就是 在 回调!先声明接口,再声明方法,把监听传过来,只不过我们这里的监听不止一个,而是用集合 维护了 一堆监听,然后再适当的时机马上去通知回调。两者有异曲同工之妙,非要说区别的话,”回调“中只有一个监听者,而这里的“观察者设计模式”中有许多个监听者。




以上,这里只是把此功能 的 核心骨架 抽取出来讲解,具体还有 “观察者接口”实现的部分等等,但是核心思想模式的理解是重要的一步!

希望对你们有帮助:)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值