观察者模式(发布/订阅模式)

- 发布 + 订阅 = 观察者模式
设计原则 - 松耦合
- 为了交互对象之间的松耦合设计而努力
- 松耦合把对象之间的互相依赖降到了最低,因此可以增加弹性,应对变化
设计模式 - 观察者模式

- 定义了对象之间的一对多依赖。当对象改变状态时,它的所有依赖者都会收到通知并自动更新。
应用
- 优点
- 松耦合。抽象耦合关系
- 可实现广播机制
- 缺点
- 广播通知耗时
- 循环依赖会导致循环调用,使系统崩溃
- 场景
- 一对多关系 - 一个对象状态的改变需要改变其他对象。
- 商品库存数量发生变化时,需要通知商品详情页、购物车等系统改变数量
- 微博或微信朋友圈发送场景
- 匿名订阅者 - 一个对象发生改变时只想要发送通知,而不需要知道接收者是谁
- 订阅微信公众号的文章,发送者通过公众号发送,不显示暴露订阅者
- 链式触发机制
- A对象的行为将影响B对象,B对象的行为将影响C对象
- 事件触发场景
- 基于Java UI的编程
- 一对多关系 - 一个对象状态的改变需要改变其他对象。
Java内置的观察者模式
Observer接口:观察者对象,监听被观察者对象数据变化。一旦数据发生变化就做出相应响应。
package java.util; import java.util.Observable; public interface Observer { void update(Observable var1, Object var2); }
Observable类:被观察者对象,管理(添加或移出)观察者对象。数据变化完成时通知所有已添加的观察者对象。
package java.util; import java.util.Observer; import java.util.Vector; public class Observable { private boolean changed = false; private Vector<Observer> obs = new Vector(); public Observable() { } public synchronized void addObserver(Observer var1) { if(var1 == null) { throw new NullPointerException(); } else { if(!this.obs.contains(var1)) { this.obs.addElement(var1); } } } public synchronized void deleteObserver(Observer var1) { this.obs.removeElement(var1); } public void notifyObservers() { this.notifyObservers((Object)null); } public void notifyObservers(Object var1) { Object[] var2; synchronized(this) { if(!this.changed) { return; } var2 = this.obs.toArray(); this.clearChanged(); } for(int var3 = var2.length - 1; var3 >= 0; --var3) { ((Observer)var2[var3]).update(this, var1); } } public synchronized void deleteObservers() { this.obs.removeAllElements(); } protected synchronized void setChanged() { this.changed = true; } protected synchronized void clearChanged() { this.changed = false; } public synchronized boolean hasChanged() { return this.changed; } public synchronized int countObservers() { return this.obs.size(); } }