Android 观察者模式

源码地址

定义

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

使用场景

  • 关联行为场景,需要注意的是,关联行为是可拆分的,而不是”组合关系“;
  • 时间多级触发场景;
  • 跨系统的消息交换场景,如消息队列、事件总线的处理机制。

简单实现

需求:模拟开发技术前线网站的订阅与发布。

  1. 观察者对象

    public class Coder implements Observer {
    
        private String name;
    
        public Coder(String name) {
            this.name = name;
        }
    
        @Override
        public void update(Observable o, Object arg) {
            System.out.println("Hi, " + name + ", 开发技术前线更新啦,内容: " + arg);
        }
    
        @Override
        public String toString() {
            return "码农:" + name;
        }
    }
    
  2. 被观察者

    public class DevTechFrontier extends Observable {
    
        public void postNewPublication(String content) {
            // 标识状态或者内容发生变化
            setChanged();
            // 通知所有观察者
            notifyObservers(content);
        }
    }
    
  3. 测试代码

    public class Test {
        public static void main(String[] args) {
            // 被观察的角色
            DevTechFrontier devTechFrontier = new DevTechFrontier();
            // 观察者
            Coder mrYang = new Coder("mr.yang");
            Coder coder1 = new Coder("coder-1");
            Coder coder2 = new Coder("coder-2");
            Coder coder3 = new Coder("coder-3");
    
            // 将观察者注册到可观察对象的观察者列表中
            devTechFrontier.addObserver(mrYang);
            devTechFrontier.addObserver(coder1);
            devTechFrontier.addObserver(coder2);
            devTechFrontier.addObserver(coder3);
    
            devTechFrontier.postNewPublication("新的一期开发技术前线周报发布啦!");
        }
    }
    
  4. 运行结果

    Hi, coder-3, 开发技术前线更新啦,内容: 新的一期开发技术前线周报发布啦!
    Hi, coder-2, 开发技术前线更新啦,内容: 新的一期开发技术前线周报发布啦!
    Hi, coder-1, 开发技术前线更新啦,内容: 新的一期开发技术前线周报发布啦!
    Hi, mr.yang, 开发技术前线更新啦,内容: 新的一期开发技术前线周报发布啦!
    

    上面的 Observer 与 Observable 是 JDK 中的内置类型。

    参看源码可以知道,Observer 是一个接口,内部有一个 update 方法,与我们常见的回调接口有些类似。Observable 则是一个类,里面包含有添加观察者、通知所有观察者等等方法,逻辑也很简单,添加观察者就是将观察者添加到集合中;通知所有观察者则是遍历加入的观察者集合,将其强转为 Observer 对象,然后再调用 update 方法来进行更新。

Android 源码中的实现

ListView 中 Adapter 的 notifyDataSetChanged() 这类方法。

BroadcastReceiver 广播也是其中一种。

实战

热门事件总线 :

  1. EventBus
  2. AndroidEventBus
  3. RxBus(java)
  4. RxBus(kotlin)

总结

  • 优点

    1. 观察者和被观察者之间是抽象耦合,应对业务变化;
    2. 增强系统灵活性、可扩展性。
  • 缺点

    在应用观察者模式时需要考虑开发效率和运行效率问题,出现多个观察者时开发、调试较为复杂,而且Java中消息的通知默认顺序执行,一个观察者卡顿,会影响整体的执行效率。在这种情况下,一般考虑采用异步的方式。

推荐阅读更多精彩内容

  • 前言 对于设计模式的学习,作者一开始是拒绝的。因为作者的Java基础和Android基础很烂。想着补一下Java坑...
    空城新月阅读 540评论 3 6
  • 观察者模式的定义 观察者定义了一个一对多的依赖关系,让一个或者多个观察者监听一个主题(被观察者)的变化。因此,当主...
    MaZH阅读 271评论 0 1
  • 前提 话不多说先看图 _ 容小可解释一下,在这个界面中,要实现在一个输入框中写入文本然后点击设置按钮,实现下面的T...
    Silence潇湘夜雨阅读 478评论 0 6
  • 观察者模式理解 观察者模式 Observer 观察者模式定义了一个一对多的依赖关系,让多个观察者对象同时监听一个主...
    Nickyzhang阅读 5,232评论 5 14
  • 关于观察者模式的一些小的Demo 以前总是用,都是从晚上进行copy。今天自己写了一个。分别定义两个接口。一个是观...
    基本密码宋阅读 94评论 0 0