釋出訂閱 VS 觀察者模式

Gu_Yan發表於2019-02-22

釋出訂閱

特點:兩者無關

  • 原理解析
    • 1.有一箇中間的介質(類)
    • 2.介質上需要提供一個訂閱的方法(on)
    • 3.介質上需要提供一個釋出的方法(emit)
  • 簡易實現
/* 1.一箇中間的介質 */
function Events() {
  this.subArr = [];
}

/* 2.介質上有一個訂閱的方法on */
Events.prototype.on = function (fn) {
  this.subArr.push(fn);
}

/* 2.介質上有一個釋出的方法emit */
Events.prototype.emit = function (params) {
  this.subArr.forEach(fn => fn(params));
}

let event = new Events();

event.on((params) => {
  console.log(params);
})

event.on((params) => {
  params = `${params} LOVE YOU`
  console.log(params);
})

event.emit('I')
複製程式碼

觀察者模式

特點:觀察者 + 被觀察者 (兩者有關係)

  • 原理解析
    • 1.被觀察者要存放在觀察者中
    • 2.被觀察者要提供一個更新資料的方法(setState)
    • 3.被觀察者需要提供一個註冊觀察者的方法(attach)
    • 4.觀察這個要提供一個方法(update)用來監控被觀察者的資料發生改變之後做出響應
  • 簡易實現
function Observer(state) { // 被觀察者
  this.state = state; // 被觀察這個的初始狀態
  this.subArr = [];
}

/* 3.被觀察者註冊觀察者的方法 */
Observer.prototype.attach = function (subject) {
  this.subArr.push(subject);
}

/* 2.被觀察者的更新狀態方法 */
Observer.prototype.setState = function (newState) {
  let oldState = this.state;
  this.state = newState;
  this.subArr.forEach(subject => subject.update(oldState, newState));
}

function Subject(name, target) { // 觀察者
  this.name = name;
  /* 1.將被觀察這個存放到觀察者中 */
  this.target = target;
}

/* 4.觀察者監控被觀察者狀態變化做出響應的方法 */
Subject.prototype.update = function (oldState, newState) {
  console.log(this.name, oldState, newState);
}

let observer = new Observer('happy');

let subject1 = new Subject('me', observer);
let subject2 = new Subject('you', observer);

observer.attach(subject1);
observer.attach(subject2);

observer.setState('sad');
observer.setState('cry');
複製程式碼

相關文章