image.png

观察者模式

定义

对象间一种一对多的依赖关系,当目标对象 Subject 的状态发生改变时,所有依赖它的对象 Observer 都会得到通知。

实质

A男孩和C男孩在M女孩的追求者列表中,当M女孩对追求者列表说我失恋了,追求者列表的A男孩和C男孩收到消息后开心的笑了,因为他们没忍住

特点

M女孩在执行添加、删除、通知操作的时候会通知所有的备胎。M女孩就相当于目标对象Subject,备胎就相当于观察者

代码

  1. //定义一个目标对象。也就是M女孩
  2. class Subject {
  3. constructor() {
  4. this.subs = [];
  5. }
  6. //添加一个备胎
  7. add(sub) {
  8. this.subs.push(sub);
  9. }
  10. //删除一个备胎
  11. remove(sub) {
  12. let idx = this.subs.findIndex(item => JSON.stringify(item) === JSON.stringify(sub))
  13. this.subs.splice(idx, 1)
  14. }
  15. //通知备胎报名
  16. notify() {
  17. this.subs.forEach(ob => {
  18. ob.update.apply(ob, Array.prototype.slice.call(arguments));
  19. })
  20. }
  21. }
  22. //定义一个观察者,也就是备胎
  23. class Observer {
  24. constructor() {
  25. this.name = name
  26. }
  27. update() {
  28. console.log("我是备胎" + this.name);
  29. }
  30. }
  31. const boy1 = new Observer('boy1');
  32. const boy2 = new Observer('boy2');
  33. const boy3 = new Observer('boy3');
  34. const boy4 = new Observer('boy4');
  35. const subject = new Subject();
  36. subject.add(boy1);
  37. subject.add(boy2);
  38. subject.add(boy3);
  39. subject.add(boy4);
  40. subject.notify("我失恋了");

发布订阅者模式

定义

对象间一种一对多的依赖关系,当目标对象指定的动作发生改变时,订阅该动作的依赖对象会收到相应的通知。

实质

男孩A和男孩B分别在抖音和火山直播平台关注了主播。主播在抖音上发布消息,男孩A就可以收到消息,女孩在火山上发布消息,男孩B就可以收到消息。那么直播平台就充当了一个事件调度中心。

特点

事件调度中心执行添加/删除订阅者和发布操作。

代码

  1. //定义一个事件调度中心
  2. class PubSub {
  3. constructor() {
  4. //事件缓存列表
  5. this.eventList = Object.create(null);
  6. }
  7. //订阅
  8. subscribe(event, fn) {
  9. if (Array.isArray(this.eventList[event])) {
  10. this.eventList[event].push(fn);
  11. }
  12. }
  13. //取消订阅
  14. unSubscribe(key) {
  15. delete this.eventList[key];
  16. }
  17. //发布
  18. publish(event, ...args) {
  19. const fns = this.eventList[event] || [];
  20. //如果该平台下面没有订阅者,就返回
  21. if (fns.length == 0) {
  22. return false;
  23. }
  24. //通知该平台下面的订阅者更新
  25. fns.forEach((fn) => {
  26. fn.call(this, args)
  27. })
  28. return this;
  29. }
  30. }
  31. //订阅是基于抖音/雅虎直播平台传入自定义事件进行订阅
  32. //发布也是基于抖音/雅虎直播平台触发自定义事件的
  33. const pubSub = new PubSub();
  34. pubSub.subscribe("抖音", (msg) => {
  35. console.log("抖音: " + msg);
  36. });
  37. pubSub.subscribe("雅虎", (msg) => {
  38. console.log("雅虎: " + msg);
  39. });
  40. pubSub.publish("抖音", "我失恋了")
  41. pubSub.publish("雅虎", "我恋爱了")

区别

观察者模式

目标直接将通知分发到观察者身上

发布订阅者模式

目标首先是将通知分发到事件调度中心,事件调度中心再通过订阅者具体订阅的类型分发到不同的订阅者身上

总结

从代码角度看,观察者的subs是一个数组,该数组用来存储订阅者对应的自定义事件。发布订阅者模式的subs是一个对象,该对象用来存储目标主题相关的事件。