`
dengzhangtao
  • 浏览: 677638 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

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

 
阅读更多

观察者模式,是一种非常常见的设计模式,在很多系统中随处可见,尤其是涉及到数据状态发生变化需要通知的情况下。
本文以AbstractCursor为例子,展开分析。
观察者模式,Observer Pattern,是一个很实用的模式,本人曾经接触到的各种平台以及曾经参与项目中打印模板解释器中都用到了此模式。

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

2.结构


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


观察者分成了两个系列。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public abstract class AbstractCursor {
    //定义管理器
    DataSetObservable mDataSetObservable = new DataSetObservable();
    ContentObservable mContentObservable = new ContentObservable();
     
    //注册和卸载两类观察者
    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(boolean selfChange) {
        synchronized (mSelfObserverLock) {
            mContentObservable.dispatchChange(selfChange);
            if (mNotifyUri != null && selfChange) {
                mContentResolver.notifyChange(mNotifyUri, mSelfObserver);
            }
        }
    }
 
    protected void notifyDataSetChange() {
        mDataSetObservable.notifyChanged();
    }
}

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public abstract class Observable<T> {
    /**
     * 观察者列表
     */
    protected final ArrayList<T> mObservers = new ArrayList<T>();
 
    public void registerObserver(T observer) {
        if (observer == null) {
            throw new IllegalArgumentException("The observer is null.");
        }
        synchronized(mObservers) {
            if (mObservers.contains(observer)) {
                throw new IllegalStateException("Observer " + observer + " is already registered.");
            }
            mObservers.add(observer);
        }
    }
 
 
    public void unregisterObserver(T observer) {
        if (observer == null) {
            throw new IllegalArgumentException("The observer is null.");
        }
        synchronized(mObservers) {
            int index = mObservers.indexOf(observer);
            if (index == -1) {
                throw new IllegalStateException("Observer " + observer + " was not registered.");
            }
            mObservers.remove(index);
        }
    }
     
    public void unregisterAll() {
        synchronized(mObservers) {
            mObservers.clear();
        }       
    }
}

  和

1
2
3
4
5
6
7
8
9
10
11
12
13
public class DataSetObservable extends Observable<DataSetObserver> {
    /**
     * 数据发生变化时,通知所有的观察者
     */
    public void notifyChanged() {
        synchronized(mObservers) {
            for (DataSetObserver observer : mObservers) {
                observer.onChanged();
            }
        }
    }
    //... ... (其他方法)
}

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

1
2
3
4
5
public abstract class DataSetObserver {
    public void onChanged() {
        // Do nothing
    }
}

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

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

  ContentObserver也是类似。

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

分享到:
评论

相关推荐

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

    在Android SDK源码中,观察者模式被广泛应用于对象间的通信,例如数据变更时的通知机制。本文将深入探讨这种模式在Android中的应用,以AbstractCursor为例进行解析。 在观察者模式中,有两个关键角色:观察者...

    Android高级应用源码-一键锁屏功能源码.zip

    10. **代码组织和设计模式**: 分析源码的结构,可以学习到良好的代码组织方式,比如模块化、面向对象设计,以及可能用到的设计模式,如单例模式、观察者模式等。 通过研究这个源码,开发者不仅可以掌握一键锁屏的...

    Android SDK开发物超所值的几本好书2

    通过分析Android源码,这本书揭示了系统内部的设计模式和最佳实践,帮助开发者提高代码质量和可维护性。它涵盖了单例模式、工厂模式、观察者模式以及MVC、MVP和MVVM架构模式。 6. 《安卓艺术探索》 这本书关注于...

    android源码 jar包

    5. **学习设计模式**:Android源码中广泛应用了设计模式,如观察者模式、单例模式等,阅读源码能提升开发者的设计能力。 总之,"android源码 jar包" 是一个宝贵的资源,它能够帮助进阶的Android开发者提升技能,...

    Android应用源码之俄罗斯方块游戏源码-IT计算机-毕业设计.zip

    在Android平台上进行移动应用开发,尤其对于初学者或者毕业设计的学生来说,理解并分析已有的应用源码是提升技能的重要途径。本篇将深入探讨“Android应用源码之俄罗斯方块游戏源码”,从中提炼出关键知识点,帮助...

    Android 万年历源码.zip

    源码中可能运用了单例模式、观察者模式等设计模式,如单例的ContentProvider实例,观察者模式用于监听日历事件的变化。 12. **UI交互**: 通过OnClickListener、OnTouchListener等接口,实现用户点击、滑动等交互...

    Android高级应用源码-android 豆瓣网客户端.zip

    - **LiveData或RxJava**:数据观察者模式,用于实现实时数据更新并保持UI同步。 - **Dagger2或Hilt**:依赖注入框架,简化对象创建和管理。 - **Butter Knife或ViewBinding**:视图绑定工具,减少 findViewById() 的...

    应用源码之51CTO下载-自定义锁屏实现----仿正点闹钟.zip

    - 源码可能包含单例模式、观察者模式、工厂模式等设计模式,这对于理解和优化代码结构至关重要。 通过对这些关键知识点的学习,开发者不仅能理解这个自定义锁屏应用的工作原理,还能提升Android应用开发的能力。...

    pro android games源码

    5. **游戏架构设计**: 熟悉MVC(模型-视图-控制器)、MVVM(模型-视图-ViewModel)等设计模式,对于构建可扩展和维护的游戏至关重要。 6. **性能优化**: Android设备性能各异,优化游戏性能是关键。这包括减少渲染...

    MJAndroid应用开发书的源码【源代码】

    - Android开发中常用的设计模式包括单例模式、工厂模式、观察者模式等,源码分析可以帮助理解如何在实际项目中应用这些模式。 12. **第三方库** - 开发者常使用第三方库如ButterKnife(视图注入)、Retrofit...

    安卓Android源码——LumaQQ- qq 代码.zip

    源码中会体现出各种设计模式的应用,如单例模式、工厂模式、观察者模式等,它们帮助代码结构清晰,易于维护。 9. **Android框架扩展** LumaQQ可能使用了第三方库,如RxJava进行响应式编程,Dagger进行依赖注入,...

    Android开会计时软件源码

    5. **设计模式**:标签中提到了"优秀设计模式",源码可能采用了单例模式、观察者模式或者MVC(模型-视图-控制器)、MVVM(模型-视图-ViewModel)等架构模式,以提高代码的可读性和可维护性。 6. **事件监听**:用户...

    安卓Android源码——Android高级应用源码和思维导图.zip

    - **设计模式**:识别并理解源码中使用的常见设计模式,如单例、工厂、观察者等。 - **问题解决**:通过阅读和分析他人的代码,提高解决问题的能力,遇到类似问题时能更快找到解决方案。 总之,这个压缩包对于希望...

    android api sources 源码

    - **学习设计模式**:Android源码中广泛运用了各种设计模式,如单例、工厂、观察者等,这对于提升编程技巧很有帮助。 - **自定义实现**:对于Android的一些默认行为不满意,可以基于源码进行定制和扩展。 4. **...

    安卓仓库管理系统源码(毕业设计 Android)

    11. **响应式编程**:如果使用了RxJava或 LiveData,会涉及到观察者模式和响应式编程的概念,用于异步数据流处理。 12. **UI优化**:考虑到用户体验,可能会涉及性能优化,如使用AsyncTask、Loader或JobScheduler...

    Android Tools4U源码.rar

    源码中可能运用了多种设计模式,如单例模式、工厂模式、观察者模式等,这些模式在解决特定问题时能提高代码的可读性和可维护性。此外,源码还可能展示了如何有效地管理内存,避免内存泄漏,以及如何优化UI性能,提升...

    Android应用源码之(游戏视图与系统组件.zip

    - 观察者模式用于事件处理,如按键事件、触摸事件。 - 单例模式用于管理全局资源,如音乐播放器、网络连接等。 - 工厂模式用于动态创建游戏对象。 以上就是“Android应用源码之(游戏视图与系统组件.zip”中可能...

    Android-kotlin开发商用的电商项目

    - **LiveData**:观察者模式实现的数据容器,保证UI实时更新,同时处理生命周期问题。 - **Room数据库**:Google提供的SQLite ORM库,简化数据库操作。 - **Coroutines**:协程处理异步操作,解决Android中的线程...

    Android项目源码v2ex技术社区非官方客户端

    LiveData是一种观察者模式的实现,用于在数据变化时通知视图进行更新。 8. **Permissions**:如果应用需要访问网络或者存储权限,那么可能包含了运行时权限管理的代码,以确保在需要的时候向用户请求相应的权限。 ...

Global site tag (gtag.js) - Google Analytics