1. 前言
观察者模式本来是打算在前一篇中和动态代理模式一起写的,最后还是决定拿出来单独写一篇了。观察者模式还是比较好理解的,代码也比较简单,所以这一篇内容可能相对比较少吧。
2. 观察者模式
观察者模式又称为发布订阅模式,是对象的行为模式。观察者模式里主要是两种类型的对象,一个种是被订阅者,另一种是订阅者。在观察者模式中,一个被订阅者可以被多个订阅者监视,所以被订阅者和订阅者之间形成了一种一对多的关联关系。当被订阅者发生变化时,就会通知订阅者,之后订阅者会做出相应的行为。
其实被订阅者与订阅者之间的关系,类似于数学中的自变量和应变量之间的关系。在实际生活中也有许多观察者模式的实例,比如淘宝账号的收藏功能。当你收藏某个店铺之后,当该店铺中有新的商品售卖,你就会收到店铺发来的提示信息。其实店铺就是被观察者,而你的淘宝账号就是观察者。
在Java中要实现观察者模式,需要依靠一个类和一个接口。
一个类,即java.util包下的Observable类。在API中找到这个类,介绍内容如下:
如何实现观察者模式,在API中已经说得很清楚了,这里要注意类介绍里的最后一句话,也就是“当且仅当equals 方法为两个观察者返回 true 时,才认为它们是相同的。”这一句。查看Observable类的源码如下图所示:
这里没有看到Observable类重写equals方法,也就是说这里比较两个观察者是否相同,是通过比较它们的地址来判断的。而且从图中标注可以看到notifyObservers这个方法是线程安全的。
一个接口,即java.util包下的Observer接口,通过查API,如图,我们发现这个接口只有一个update抽象方法。而且API中说得很清楚,只要被观察者一改变,就会自动调用该方法。
3. 具体实现
这里为了测试观察者模式,我以订阅一个书店为例,模拟当一个书店有新书上架发售的时候,就通知订阅该书店的用户有新书上架发售了。很明显,书店就是被订阅者,用户就是订阅者。
3.1 被订阅者
作为书店,自然会有一个图书列表,还有一个订阅者列表,当然还要有管理这些列表的方法。因此具体实现如下:
3.2 订阅者
订阅者要实现Observer接口,而这个接口只有一个update抽象方法,所以订阅者类很简单,如图:
为了方便模拟,可以多编写几个订阅者类,因为代码基本相似,所以我就只贴一个了。
3.3 测试类
在测试类中,首先获取到被订阅者对象,然后向其添加订阅者,最后模拟上级发售新的图书即可,代码如下:
测试结果如下:
从测试结果可以看出,当书店里新上架发售一本书的时候,订阅该书店的两个订阅者就会收到通知。
4. 总结
观察者模式比动态代理模式好理解的多,实现起来逻辑也比较简单。这一篇就写这些吧。因为最近在学着撘一个自己的SSM小框架,后面我会陆续写一点搭建过程中学到的内容。