观察者模式定义
在对象之间定义定义一对多的依赖关系,使得一个对象的变化可以自动地通知到所依赖的其它对象。
该模式的UML类图可以表达如下,
图中被观察者(Observerable)和观察者(Observer)之间形成一对多的关系,其中,
Observerable:可被观察的对象,属于一对多关系中的一。
Observer:希望接受被观察的对象变化通知的对象,属于一对多关系中的多。
基本的交互过程为,
1、Observerable持有注册的观察者列表,观察者的注册和注销通过attach()和detach()完成。
2、当Observerable发生变化时,将会通过notify()通知注册的所有观察者。
3、观察者通过接口onNotification()来获取变化通知,如果不想接受变化通知,可以随时通过detach方法注销观察。
被观察者和观察者之间的消息通知通过如下几个基本接口定义来实现,
Observerable.attach():注册观察者,添加一个观察者到通知列表。
Observerable.detach():注销观察者,从通知列表中删除一个观察者。Observerable.notify():通知所有观察者,将会调用观察者的onNotification接口。
Observer.onNotification():观察者获取通知消息的接口。
除此之外,观察者模式并不需要其它更多接口,从而实现了被观察者和观察者的松耦合。
简单的Java接口实现
Java中可以通过接口来实现观察者模式,UML类图如下,
代码样例见文章结尾。
通过Java自带的实用工具类库
在JDK自带的实用工具类库(Java.util.Observer)有对观察者模式的支持,UML类图可以表达如下,
其中Observerable是一个抽象类,并不是一个接口,也意味着被观察的主题不能继承其它抽象类了,这也是其应用的缺点。
代码样例见文章结尾。
自定义观察者和监听者
为了方便的使用观察者,有时候需要自定义的观察者监听者,提供更加清晰易懂的方法接口。如下UML类图中,
其添加了自定义的监听者(AbstractAssertListener和AbstractLogListener),分别提供onAssert()和onLog()方法,用于接受当发生assert/log事件的通知消息。
代码样例见文章结尾。
代码样例
代码仓库地址:http://git.oschina.net/pphh/designPatterns,可以通过如下git clone命令获取仓库代码,
git clone git@git.oschina.net:pphh/designPatterns.git
上述代码样例在文件路径designPatterns\java\observer中。
参考资料
《设计模式-可复用面向对象软件的基础》
《Head First 设计模式》