直接 3W

观察者模式(Observer)

观察者模式指的是一个对象(Subject)维持一系列依赖于它的对象(Observer),当有关状态发生变更时 Subject 对象则通知一系列 Observer 对象进行更新。

在观察者模式中,Subject 对象拥有添加、删除和通知一系列 Observer 的方法等等,而 Observer 对象拥有更新方法等等。

  1. // 定义一个主体对象
  2. class Subject {
  3. constructor() {
  4. this.Observers = [];
  5. }
  6. add(observer) {
  7. //添加
  8. this.Observers.push(observer);
  9. }
  10. remove(observer) {
  11. //移除
  12. this.Observers.filter((item) => item === observer);
  13. }
  14. notify() {
  15. this.Observers.forEach((item) => {
  16. item.update();
  17. });
  18. }
  19. }
  20. //定义观察着对象
  21. class Observer {
  22. constructor(name) {
  23. this.name = name;
  24. }
  25. update() {
  26. console.log(`my name is:${this.name}`);
  27. }
  28. }
  29. //测试
  30. let sub = new Subject();
  31. let obs1 = new Observer("leaf111");
  32. let obs2 = new Observer("leaf222");
  33. sub.add(obs1);
  34. sub.add(obs2);
  35. sub.notify();

发布订阅模式(Publisher && Subscriber)

发布订阅模式指的是希望接收通知的对象(Subscriber)基于一个主题通过自定义事件订阅主题,被激活事件的对象(Publisher)通过发布主题事件的方式通知各个订阅该主题的 Subscriber 对象。

  1. let pubSub = {
  2. subs: [],
  3. subscribe(key, fn) {
  4. //订阅
  5. if (!this.subs[key]) {
  6. this.subs[key] = [];
  7. }
  8. this.subs[key].push(fn);
  9. },
  10. publish(...arg) {
  11. //发布
  12. let args = arg;
  13. let key = args.shift();
  14. let fns = this.subs[key];
  15. if (!fns || fns.length <= 0) return;
  16. for (let i = 0, len = fns.length; i < len; i++) {
  17. fns[i](args);
  18. }
  19. },
  20. unSubscribe(key) {
  21. delete this.subs[key];
  22. },
  23. };
  24. //测试
  25. pubSub.subscribe("name", (name) => {
  26. console.log(`your name is ${name}`);
  27. });
  28. pubSub.subscribe("gender", (gender) => {
  29. console.log(`your name is ${gender}`);
  30. });
  31. pubSub.publish("name", "leaf333"); // your name is leaf333
  32. pubSub.publish("gender", "18"); // your gender is 18

js 设计模式之[观察者模式]、[发布订阅模式] - 图1

如上图所示:

1、在观察者模式中,观察者是知道 Subject 的,Subject 一直保持对观察者进行记录。然而,在发布订阅模式中,发布者和订阅者不知道对方的存在。它们只有通过消息代理进行通信。

2、在发布订阅模式中,组件是松散耦合的,正好和观察者模式相反。

3、观察者模式大多数时候是同步的,比如当事件触发,Subject 就会去调用观察者的方法。而发布-订阅模式大多数时候是异步的(使用消息队列)。