Head First 设计模式02 —— 观察者模式

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

image-20241227094440892
  • 发布 + 订阅 = 观察者模式

设计原则 - 松耦合

  • 为了交互对象之间的松耦合设计而努力
  • 松耦合把对象之间的互相依赖降到了最低,因此可以增加弹性,应对变化

设计模式 - 观察者模式

  • 定义了对象之间的一对多依赖。当对象改变状态时,它的所有依赖者都会收到通知并自动更新。

应用

  • 优点
    • 松耦合。抽象耦合关系
    • 可实现广播机制
  • 缺点
    • 广播通知耗时
    • 循环依赖会导致循环调用,使系统崩溃
  • 场景
    • 一对多关系 - 一个对象状态的改变需要改变其他对象。
      • 商品库存数量发生变化时,需要通知商品详情页、购物车等系统改变数量
      • 微博或微信朋友圈发送场景
    • 匿名订阅者 - 一个对象发生改变时只想要发送通知,而不需要知道接收者是谁
      • 订阅微信公众号的文章,发送者通过公众号发送,不显示暴露订阅者
    • 链式触发机制
      • 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();
        }
    }