发布订阅 和 观察者模式

发布订阅 和 观察者模式

    • 一.观察者模式
    • 二.发布订阅模式
    • 三.观察者模式 和 发布订阅模式的差异

一.观察者模式

观察者模式定义了观察者和被观察者的一对多的依赖关系,它们之间存在直接的联系;当被观察者发布通知时,所有依赖于它的观察者都将得到通知。


╭─────────────╮  Fire Event  ╭──────────────╮
│             │─────────────>│              │
│   Subject   │              │   Observer   │
│             │<─────────────│              │
╰─────────────╯  Subscribe   ╰──────────────╯

class Subject {
    constructor() {
        this.observers = [];
    }
 
    add(observer) {
        this.observers.push(observer);
    }
 
    notify(...args) {
        this.observers.forEach(observer => observer.update(...args));
    }
}
 
class Observer {
    update(...args) {
        console.log(...args);
    }
}
 
// 创建观察者ob1
let ob1 = new Observer();
// 创建观察者ob2
let ob2 = new Observer();
// 创建目标sub
let sub = new Subject();
// 目标sub添加观察者ob1 (目标和观察者建立了依赖关系)
sub.add(ob1);
// 目标sub添加观察者ob2
sub.add(ob2);
// 目标sub触发SMS事件(目标主动通知观察者)
sub.notify('I fired `SMS` event');

二.发布订阅模式

发布订阅模式中,发布者发布消息时不会将消息直接发送给订阅者,发布者和订阅者之间不存在直接的联系;在发布者和订阅者之间存在第三方平台,称为消息代理或调度中心或中间件,它维持着发布者和订阅者之间的联系,可以处理所有发布者发布的消息并将它们分发给对应的订阅者,实现了发布者与订阅者之间的解耦。

╭─────────────╮                 ╭───────────────╮   Fire Event   ╭──────────────╮
│             │  Publish Event  │               │───────────────>│              │
│  Publisher  │────────────────>│ Event Channel │                │  Subscriber  │
│             │                 │               │<───────────────│              │
╰─────────────╯                 ╰───────────────╯    Subscribe   ╰──────────────╯

class PubSub {
    constructor() {
        this.subscribers = [];
    }
     
    subscribe(topic, callback) {
        let callbacks = this.subscribers[topic];
        if (!callbacks) {
            this.subscribers[topic] = [callback];
        } else {
            callbacks.push(callback);
        }
    }
     
    publish(topic, ...args) {
        let callbacks = this.subscribers[topic] || [];
        callbacks.forEach(callback => callback(...args));
    }
}
 
// 创建事件调度中心,为订阅者和发布者提供调度服务
let pubSub = new PubSub();
// A订阅了SMS事件(A只关注SMS本身,而不关心谁发布这个事件)
pubSub.subscribe('SMS', console.log);
// B订阅了SMS事件
pubSub.subscribe('SMS', console.log);
// C发布了SMS事件(C只关注SMS本身,不关心谁订阅了这个事件)
pubSub.publish('SMS', 'I published `SMS` event');

三.观察者模式 和 发布订阅模式的差异

  • 观察者模式中,观察者是知道Subject的,Subject一直保持对观察者进行记录。然而,在发布订阅模式中,发布者和订阅者不知道对方的存在。它们只有通过消息代理进行通信。
  • 发布订阅模式中,组件是松散耦合的,正好和观察者模式相反。
  • 观察者模式大多数时候是同步的,比如当事件触发,Subject就会去调用观察者的方法。而发布-订阅模式大多数时候是异步的(使用消息队列)。
  • 观察者 模式需要在单个应用程序地址空间中实现,而发布-订阅更像交叉应用模式。

尽管它们之间有区别,但有些人可能会说发布-订阅模式是观察者模式的变异,因为它们概念上是相似的。

你可能感兴趣的:(前端,观察者模式)