Observer(觀察者模式)

目的

建立一種一對多的相依關係,當一個物件的狀態發生改變時,所有相依他的物件都將得到通知,並且自動更新。

Code


// 观察的主题(目标对象),相当于发布者
class Subject {
  constructor() {
    this.subs = [];
    this.state = "张三";//触发更新的状态
  }
  //新增两个对于name的操作 获取/更新
  getState() {
    return state;
  }
  setState(state) {
    if (this.state === state) {
      console.log('不能设为之前的name,无效');
      return;
    }
    this.state = state;
    this.notify(); // 有更新,触发通知!【原本手动触发通知的,现在根据数据变化来触发】
  }
  addSub(sub) {
    this.subs.push(sub);
    console.log(this.subs)
  }
  removeSub(sub) {
    const idx = this.subs.findIndex(i => i === sub);
    if (idx === -1) {
      console.log('不存在该观察者');
      return;
    }
    this.subs.splice(idx, 1);
  }
  notify() {
    this.subs.forEach(sub => {
      sub.update();// 与观察者原型方法update对应!
    });
  }
}

// 观察人,相当于订阅者
class Observer {
  update() {
    console.log('update');
  }
}

// 测试代码
const subject = new Subject();
const ob = new Observer();
const ob2 = new Observer();
ob2.update = function () { //修改update方法,实现不同逻辑
  console.log('laifeipeng');
}

//目标添加观察者了
subject.addSub(ob);
subject.addSub(ob2);

//目标发布消息调用观察者的更新方法了
// subject.notify(); // 不使用手动触发,通过内部状态的设置来触发
subject.setState('李四');
// update
// laifeipeng

subject.setState('李四');
// 不能设为之前的name,无效

流程

  • 首先各自都new 出一個實體

  • 再把ob / ob2 增加到原始 subject 中,讓 subject 可以追蹤

  • 所以當subject.setState之後,底下的 ob / ob2 都獲得通知,更新狀態。

優點

  • 支持簡單的廣播通信,自動通知已經訂閱的物件

  • 目標物件與觀察者之間的抽象耦合關係,能夠單獨擴展與重用

  • 增加靈活性

  • 觀察者:解耦,讓耦合的雙方都依賴於抽象,而不是依賴於實體,使得各自變化不會影響另一邊的邊畫。

缺點

  • 過度使用,導致物件與物件間的聯繫弱化,導致程式難以維護和理解

Last updated