发布订阅 VS 观察者模式

260 阅读1分钟

发布订阅

特点:两者无关

  • 原理解析
    • 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');