Android设计模式系列(2)--SDK源码之观察者模式

简介: 原文链接:http://www.cnblogs.com/qianxudetianxia/archive/2011/08/07/2129731.html观察者模式,是一种非常常见的设计模式,在很多系统中随处可见,尤其是涉及到数据状态发生变化需要通知的情况下。

原文链接:http://www.cnblogs.com/qianxudetianxia/archive/2011/08/07/2129731.html


观察者模式,是一种非常常见的设计模式,在很多系统中随处可见,尤其是涉及到数据状态发生变化需要通知的情况下

本文以AbstractCursor为例子,展开分析。
观察者模式,Observer Pattern,是一个很实用的模式,本人曾经接触到的各种平台以及曾经参与项目中打印模板解释器中都用到了此模式。

1.意图
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
热门词汇:依赖 发布-订阅 事件 通知 更新 监听 

2.结构


这是一个最简单的观察者模式,目标对象能够添加和删除观察者,当自己某种状态或者行为发生改变时,可通过notify通知注册的观察者进行更新操作。
分析AbstractCursor的具体情况,我们发现实际工作有时需要对观察者进行统一管理,甚至观察者类型有很多种而又可以分成几个系列,这个时候是要复杂的多,通过合理的分层这个问题很好解决。下面根据具体情况,我们画出android中abstractCurosr中用到的观察者模式结构图:


观察者分成了两个系列。

3.代码
列举其中相关核心代码如下:

public abstract class AbstractCursor {
    //定义管理器
    DataSetObservable mDataSetObservable = newDataSetObservable();
    ContentObservable mContentObservable = newContentObservable();
     
    //注册和卸载两类观察者
    public void registerContentObserver(ContentObserver observer) {
        mContentObservable.registerObserver(observer);
    }
 
    public void unregisterContentObserver(ContentObserver observer) {
        // cursor will unregister all observers when it close
        if(!mClosed) {
            mContentObservable.unregisterObserver(observer);
        }
    }
 
    public void registerDataSetObserver(DataSetObserver observer) {
        mDataSetObservable.registerObserver(observer);
         
    }
 
    public void unregisterDataSetObserver(DataSetObserver observer) {
        mDataSetObservable.unregisterObserver(observer);
    }
 
    //2类通知方法
    protected void onChange(booleanselfChange) {
        synchronized(mSelfObserverLock) {
            mContentObservable.dispatchChange(selfChange);
            if(mNotifyUri != null&& selfChange) {
                mContentResolver.notifyChange(mNotifyUri, mSelfObserver);
            }
        }
    }
 
    protected void notifyDataSetChange() {
        mDataSetObservable.notifyChanged();
    }
}

再看看Observable<T>类和DataSetObservable类:

?

  

public abstract class Observable<T> {
    /**
     * 观察者列表
     */
    protected final ArrayList<T> mObservers = newArrayList<T>();
 
    public void registerObserver(T observer) {
        if(observer == null) {
            thrownewIllegalArgumentException("The observer is null.");
        }
        synchronized(mObservers) {
            if(mObservers.contains(observer)) {
                thrownewIllegalStateException("Observer " + observer + " is already registered.");
            }
            mObservers.add(observer);
        }
    }
 
 
    public void unregisterObserver(T observer) {
        if(observer == null) {
            thrownewIllegalArgumentException("The observer is null.");
        }
        synchronized(mObservers) {
            intindex = mObservers.indexOf(observer);
            if(index == -1) {
                thrownewIllegalStateException("Observer " + observer + " was not registered.");
            }
            mObservers.remove(index);
        }
    }
     
    public void unregisterAll() {
        synchronized(mObservers) {
            mObservers.clear();
        }       
    }
}

?

public class DataSetObservable extends Observable<DataSetObserver> {
    /**
     * 数据发生变化时,通知所有的观察者
     */
    public void notifyChanged() {
        synchronized(mObservers) {
            for(DataSetObserver observer : mObservers) {
                observer.onChanged();
            }
        }
    }
    //... ... (其他方法)
}

  观察者DataSetObserver类是一个抽象类:

?

 

public abstract class DataSetObserver {
    public void onChanged() {
        // Do nothing
    }
}

 所以我们具体看它的子类:

public class AlphabetIndexer extends DataSetObserver{
    /*
     * @hide 被android系统隐藏起来了
     */
    @Override
    public void onChanged() {
        //观察到数据变化,观察者做自己该做的事情
        super.onChanged();
        mAlphaMap.clear();
    }
}

 ContentObserver也是类似。

4.效果
(1).行为型模式
(2).目标和观察者间的抽象耦合(经典实现)。
(3).支持广播通信(相信这点android开发者看到后应该有启发吧)。
(4).注意意外的更新,这也是观察者更新进行管理的原因之一。

相关文章
|
5月前
|
开发工具 Android开发
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
684 11
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
设计模式 存储 人工智能
389 0
|
8月前
|
设计模式 存储 缓存
Netty源码—9.性能优化和设计模式
本文主要介绍了Netty的两大性能优化工具、FastThreadLocal的源码和总结、Recycler的设计理念/使用/四个核心组件/初始化/对象获取/对象回收/异线程收割对象和总结,以及Netty设计模式的单例模式和策略模式。
269 53
|
9月前
|
XML 搜索推荐 Android开发
Android改变进度条控件progressbar的样式(根据源码修改)
本文介绍了如何基于Android源码自定义ProgressBar样式。首先分析了系统源码中ProgressBar样式的定义,发现其依赖一张旋转图片实现动画效果。接着分两步指导开发者实现自定义:1) 模仿源码创建一个旋转动画XML文件(放置在drawable文件夹),修改图片为自定义样式;2) 在UI控件中通过`indeterminateDrawable`属性应用该动画。最终实现简单且个性化的ProgressBar效果,附带效果图展示。
600 2
|
10月前
|
NoSQL 应用服务中间件 PHP
布谷一对一直播源码android版环境配置流程及功能明细
部署需基于 CentOS 7.9 系统,硬盘不低于 40G,使用宝塔面板安装环境,包括 PHP 7.3(含 Redis、Fileinfo 扩展)、Nginx、MySQL 5.6、Redis 和最新 Composer。Swoole 扩展需按步骤配置。2021.08.05 后部署需将站点目录设为 public 并用 ThinkPHP 伪静态。开发环境建议 Windows 操作系统与最新 Android Studio,基础配置涉及 APP 名称修改、接口域名更换、包名调整及第三方登录分享(如 QQ、微信)的配置,同时需完成阿里云与腾讯云相关设置。
|
设计模式 存储 Java
「全网最细 + 实战源码案例」设计模式——责任链模式
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,允许将请求沿着处理者链进行发送。每个处理者可以处理请求或将其传递给下一个处理者,从而实现解耦和灵活性。其结构包括抽象处理者(Handler)、具体处理者(ConcreteHandler)和客户端(Client)。适用于不同方式处理不同种类请求、按顺序执行多个处理者、以及运行时改变处理者及其顺序的场景。典型应用包括日志处理、Java Web过滤器、权限认证等。
274 13
「全网最细 + 实战源码案例」设计模式——责任链模式
|
设计模式 存储 算法
「全网最细 + 实战源码案例」设计模式——命令模式
命令模式(Command Pattern)是一种行为型设计模式,将请求封装成独立对象,从而解耦请求方与接收方。其核心结构包括:Command(命令接口)、ConcreteCommand(具体命令)、Receiver(接收者)和Invoker(调用者)。通过这种方式,命令的执行、撤销、排队等操作更易扩展和灵活。 适用场景: 1. 参数化对象以操作。 2. 操作放入队列或远程执行。 3. 实现回滚功能。 4. 解耦调用者与接收者。 优点: - 遵循单一职责和开闭原则。 - 支持命令组合和延迟执行。 - 可实现撤销、恢复功能。 缺点: - 增加复杂性和类数量。
407 14
「全网最细 + 实战源码案例」设计模式——命令模式
|
设计模式 算法 开发者
「全网最细 + 实战源码案例」设计模式——策略模式
策略模式(Strategy Pattern)是一种行为型设计模式,用于定义一系列可替换的算法或行为,并将它们封装成独立的类。通过上下文持有策略对象,在运行时动态切换算法,提高代码的可维护性和扩展性。适用于需要动态切换算法、避免条件语句、经常扩展算法或保持算法独立性的场景。优点包括符合开闭原则、运行时切换算法、解耦上下文与策略实现、减少条件判断;缺点是增加类数量和策略切换成本。示例中通过定义抽象策略接口和具体策略类,结合上下文类实现动态算法选择。
464 8
「全网最细 + 实战源码案例」设计模式——策略模式
|
设计模式 SQL 算法
「全网最细 + 实战源码案例」设计模式——模板方法模式
模板方法模式是一种行为型设计模式,定义了算法的骨架并在父类中实现不变部分,将可变部分延迟到子类实现。通过这种方式,它避免了代码重复,提高了复用性和扩展性。具体步骤由抽象类定义,子类实现特定逻辑。适用于框架设计、工作流和相似算法结构的场景。优点包括代码复用和符合开闭原则,缺点是可能违反里氏替换原则且灵活性较低。
332 7
「全网最细 + 实战源码案例」设计模式——模板方法模式
|
设计模式 存储 安全
「全网最细 + 实战源码案例」设计模式——组合模式
组合模式(Composite Pattern)是一种结构型设计模式,用于将对象组合成树形结构以表示“部分-整体”的层次结构。它允许客户端以一致的方式对待单个对象和对象集合,简化了复杂结构的处理。组合模式包含三个主要组件:抽象组件(Component)、叶子节点(Leaf)和组合节点(Composite)。通过这种模式,客户端可以统一处理简单元素和复杂元素,而无需关心其内部结构。适用于需要实现树状对象结构或希望以相同方式处理简单和复杂元素的场景。优点包括支持树形结构、透明性和遵循开闭原则;缺点是可能引入不必要的复杂性和过度抽象。
403 22