本篇文章总结一下观察者模式,主要从以上几点介绍。
概念介绍
观察模式是我们在开发过程中经常遇到的一种设计模式,这里先来介绍一下概念。
从字面意思上去理解,所谓的观察者模式,首先有观察者(一个或者多个),被观察者(一个)。当被观察者状态发生变化的时候,就会去通知它的所有的观察者,然后由观察者根据被观察者的情况作出反应。观察者模式属于行为型模式。
在 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
领取专属 10元无门槛券
私享最新 技术干货