观察者模式

介绍

观察者模式是一个使用率非常高的模式,它最常用的地方是 GUI 系统,订阅 - 发布系统。因为这个模式的一个重要作用就是解耦,将被观察者和观察者解耦,使得他们之间的依赖性更小,甚至做到毫无依赖。以 GUI 系统来说,应用的 UI 具有易变性,尤其是前期随着业务的改变或者产品的需求修改,应用界面会经常性修改,但是业务逻辑基本变化不大,此时,GUI 系统需要一套机制来应对这种情况,使得 UI 层与具体的业务逻辑解耦,可以使用观察者模式。

定义

定义对象间的一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。

Subject 抽象主题,也就是被观察 (Observable) 的角色,把所有观察者的引用保存到一个集合里,并提供一个接口,可以增加和删除集合中的观察者对象

ConcreteSubject 具体主题,也就是具体被观察者,具体主题内部状态发送改变时,给所有注册过的观察者发出通知

Observer 观察者,是观察者的抽象类,定义了一个接口,使得在得到主题的更改通知时更新自己

ConcreteObserver 具体观察者,该角色实现了抽象观察者所定义的更新接口

ObserverObservable 是 JDK 中的内置类型。

Observer 接口中定义了 update 抽象方法,当 Observable 中有变化时会调用 notifyObservers 方法通知所有的观察者更新。

Android 源码中的观察者模式

Adapter 中的观察者模式

BaseAdapter 是一个观察者模式!!!

public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter {
    private final DataSetObservable mDataSetObservable = new DataSetObservable();

    public boolean hasStableIds() {
        return false;
    }
    
    public void registerDataSetObserver(DataSetObserver observer) {
        mDataSetObservable.registerObserver(observer);
    }

    public void unregisterDataSetObserver(DataSetObserver observer) {
        mDataSetObservable.unregisterObserver(observer);
    }
    
    /**
     * Notifies the attached observers that the underlying data has been changed
     * and any View reflecting the data set should refresh itself.
     */
    public void notifyDataSetChanged() {
        mDataSetObservable.notifyChanged();
    }
}
  1. AdapterView 中有一个内部类 AdapterDataSetObserver,在 ListView 中设置 Adapter 时会构建其一个内部类 AdapterDataSetObserver 的对象,该类继承自 AdapterView 的 AdapterDataSetObserver,也就是一个观察者。

  2. 接着将 AdapterDataSetObserver 对象注册到 Adapter 中,Adapter 类中有一个数据集可观察者 DataSetObservable 对象,在注册时,将 AdapterDataSetObserver 放入到 DataSetObservable 内部的一个 List 集合 mObservers 中

  3. 当数据数量发生变更时,开发者手动调用 Adapter 的 notifyDataSetChanged 方法时,会调用 DataSetObserver 的 notifyChanged 方法,notityChanged 方法中则会遍历其内部的 mObservers 集合中的所有 AdapterDataSetObserver 对象,并调用其 onChanged 方法

  4. AdapterDataSetObserver 也就是观察者对象,在 AdapterView 的内部类 AdapterDataSetObserver 的 onChanged 方法中会调用 requestLayout 方法重新进行布局,更新用户界面

AdapterView 中的 AdapterDataSetObserver 为观察者,Adapter 中的 DataSetObservable 为被观察者,当注册时将与 AdapterView 中的 AdapterDataSetObserver 对象注册到 Adapter 的 DataSetObservable 中。在数据发生变化是,通过 DataSetObservable 来通知 AdapterDataSetObserver 最后通知到 AdapterView 重新布局,完成界面刷新

BroadcastReceiver 中的观察者模式

BroadcastReceiver 是 Android 四大组件之一,它作为应用内、进程间的一种重要通信手段,能够将某个消息通过广播的形式传递给对应的广播接收器对象。接收对象需要通过 Context 的 registerReceiver 方法注册到 AMS 中,当通过 sendBroadcast 发送广播时,所以注册了对应 IntentFilter 的 BroadcastReceiver 对象就会接收到这个消息,BroadcastReceiver 的 onReceive 方法就会被调用,这就是一个典型的 发布--订阅 模式,也就是我们的观察者模式。

优点

  1. 观察者和被观察者之间抽象耦合,应对业务变化

  2. 增强系统灵活性、可扩展性

缺点

  1. 开发效率和运行效率,当一个被观察者被多个观察者订阅时调试比较复杂

  2. Java 中消息通知默认是顺序的,一个观察者卡顿,会影响整体执行效率,这种情况下,采用异步方式

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容