初识
报社与用户们
观察者模式,让有兴趣的事情发生时,你不再错过!下图是观察者模式介绍篇章中出现的最多,也是最经典的观察者模式示意图。
- 用户向报社订阅报纸后,当报社有新的报纸出版时,就会向用户进行推送。
- 用户取消订阅后,即使报社有新报纸出版,也不会向用户推送。
实现方案及缺陷
- 创建报社对象,包含各个用户对象的引用
- 当报社消息变更时,call各个用户对象的变更方法
- 若需要加入一个用户,除了创建用户对象,还需要变更报社对象
- 若需要移除一个用户,则也需要变更报社类中的方法
这样的设计思路是随着需求的变更而不停更改报社和用户对象,可扩展性差,可维护性也很差,同时不能在运行时动态替换,这可怎么玩?我们的观察者模式
闪亮登场~
出版社 + 订阅者 = 观察者模式
如上标题,是通俗易懂的释义,在观察者模式定义中,有两个名词:
- 主题(Subject),对应 出版社
- 观察者(Observer),对应 订阅者
定义
定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
优点
松耦合
- 主题只知道观察者实现了某个接口,并不知道具体的类
- 任何时候都能添加观察者
- 任何时候也能删除观察者
- 运行时可随意替换观察者
- 可独立复用主题或观察者
- 改变其中一方,并不影响另一方
案例
java内置Observer 和 Observable
Observer和Observable源码可自行查看,下面主要讲述Observable.notifyObservers()方法:changed标记位,控制是否接收主题的推送,这样的目的是让观察者有选择性的接收主题的推送内容!
package java.util;
public class Observable {
// ...
public void notifyObservers(Object arg) {
/*
* a temporary array buffer, used as a snapshot of the state of
* current Observers.
*/
Object[] arrLocal;
synchronized (this) {
if (!changed)
return;
arrLocal = obs.toArray();
clearChanged();
}
for (int i = arrLocal.length-1; i>=0; i--)
((Observer)arrLocal[i]).update(this, arg);
}
protected synchronized void clearChanged() {
changed = false;
}
}
后续待补充…