首页
学习
活动
专区
工具
TVP
发布

观察者模式详解

本篇文章总结一下观察者模式,主要从以上几点介绍。

概念介绍

观察模式是我们在开发过程中经常遇到的一种设计模式,这里先来介绍一下概念。

从字面意思上去理解,所谓的观察者模式,首先有观察者(一个或者多个),被观察者(一个)。当被观察者状态发生变化的时候,就会去通知它的所有的观察者,然后由观察者根据被观察者的情况作出反应。观察者模式属于行为型模式。

在 Android 中的接口回调属于一种特殊的观察者模式,观察者只有一个(监听器)。

在观察者模式中有以下四个重要的角色:

Subject被观察者的抽象接口,在这个接口里面,提供添加观察者和删除观察者、通知观察者的方法。

ConcreteSubject具体的被观察者,Subject 的实现类。在具体的内部发生改变时,给所有注册过的观察者发送通知。

Observer观察者的抽象接口,在这个接口里面定义了一个更新方法,当收到被观察者的通知的时候就更新。

ConcreteObserver具体的观察者,Observer 的实现类。实现 Observer 的更新方法。

图例解释

使用送奶工的图例来介绍:

送奶工就可以看做是一个被观察者,然后订奶的张三、赵四、王五就是观察者(观察送奶工有没有来),送奶工来送奶会通知各位观察者,通知他们来取奶。这个时候某六也想订奶,就可以告诉送奶工,以后他也要订奶了,以后来送奶的时候就也会通知某六了。

某一天,张三不想喝奶了,就告诉送奶工,他不再订奶了,那么以后送奶工再来送奶就不会通知张三了。

具体的代码实现

根据上面的概念,需要有一个被观察者的抽象,也就是送奶工的抽象

具体的观察者对象

观察者抽象接口

观察者具体的实现

到此关于观察者和被观察者都已经写完了,这仅仅是最简单的写法,当然 方法里面可以传递参数,具体的实现让被观察者来实现。这就具体情况具体写了。

下面写 方法来测试

实际运用实例

在 Java 中实现观察模式,需要借助系统 API 提供的类,在包 中的 和 。被观察者需要继承 Observable 类,观察者需要实现接口 并且实现其中的 方法

其实虽然系统提供了 和 ,通过看源码你会发现它们的实现和我们上面写的例子是很像的,没什么难点。 类里面主要就是有存放 的集合和方法 、 、 观察者接口 内部主要有方法

简单运用

房子的价格和我们的生活息息相关,人们都很关注房价,假设房子是被观察者,人们是观察者,当房价发生变化的时候就会通知人们,这就就是一个观察者模式,用 Java 代码体现,下面列出核心代码,具体代码见链接

被观察者

观察者

验证:

显示结果:

重点:需要将观察者一一添加到被观察者中,当被观察者对象内容发生变化的时候调用 和 来通知观察者

Android 中的观察者

在 Android 中经常用到观察者模式,最常用的就是设计点击监听事件(这是一种特殊的观察者模式,观察者只有一个)、ContentObserver、android.database.Observable 等;还有组件通讯库、 、 等。这里拿 Adapter 中的观察者模式来举例:

先来看一下 的部分源码

从源码中可以很容易的看到,这里有 当数据发生变化的时候,我们就调用 方法,这个时候 就会通知观察者作出反应。就是这么一个过程!

整个过程我们都了解了,下面就是进一步看看代码是怎么实现的:看看 做了什么

这里的 mObservers 就是观察者的集合,这些观察者是在 ListView 通过 setAdapter() 设置 Adapter 时产生的:

再来看看观察者 AdapterDataSetObserver 的部分关键代码

上面代码的主要实现部分都在它的父类,再来看看 AdapterDataSetObserver 的父类 AdapterView 的 AdapterDataSetObserver :

在源码中可以看到在 方法中调用了 方法来重新进行布局。到此 BaseAdapter 的观察模式就缕清楚了。

观察者模式的使用场景和优缺点

使用场景

事件多级触发场景

跨系统的消息交换场景,如消息队列、事件总线的处理机制

优点

解除耦合,让耦合的双方都依赖于抽象,从而使得各自的变换都不会影响到另一边的变换

缺点

在应用观察者模式时需要考虑一下开发效率和运行效率的问题,程序中包括一个被观察者,多个观察者,开发、调试等内容会比较复杂,而且在 Java 中消息的通知一般是顺序执行的,那么一个观察者卡顿,就会影响整体的执行效率,在这种情况下,一般会采用异步实现。

总结:

其实无论程序整体多复杂,观察者模式是永远不会变的,首先有一个被观察者,被观察者对象中持有观察者,当被观察者发生变化的时候,调用被观察者的方法通知观察者(这个方法内通常会是 观察者调用自己对应的方法)。

至于观察者什么时候被添加到被观察者中,观察者收到信号后如果处理,这就是具体情况具体处理了。

参考内容

https://blog.csdn.net/itachi85/article/details/50773358>

https://www.jianshu.com/p/9ee823cd94a9

https://www.2cto.com/kf/201310/253013.htm

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20191010A0LQRK00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券