IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    JavaScript - 观察者与发布订阅者模式

    Johon发表于 2022-07-01 00:00:00
    love 0
    #### 观察者模式 - 观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,其所有 `依赖者` 都会收到通知并自动更新。 - 当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。 - 可以看作 `拍卖场景` ,拍卖师观察最高标价,然后通知给其他竞价者竞价。 优点: - 观察者和被观察者是抽象耦合的,实现简单,主题和观察者之间的关系明确,适用于一对多的关系。 缺点: - 当观察者较多时,主题的通知机制可能会导致性能问题,因为每个观察者都会被直接通知。 **具体实现** ```javascript title="观察者" class Observer { constructor(name) { this.name = name } update(data) { console.log(`观察者${this.name} 收到了: ${data}`) } } ``` ```javascript title="被观察者" class Subject { constructor() { this.observers = [] } add(observer) { this.observers.push(observer) } notify(data) { this.observers.forEach((i) => i.update(data)) } delete(observer) { this.observers = this.observers.filter((i) => i !== observer) } } ``` **具体使用** ```javascript title="一个栗子" const sub = new Subject() const observer1 = new Observer('A') const observer2 = new Observer('B') sub.add(observer1) sub.add(observer2) sub.notify('一条新闻') // 观察者A 收到了: 一条新闻 // 观察者B 收到了: 一条新闻 sub.notify('今天的天气是晴天') // 观察者A 收到了: 今天的天气是晴天 // 观察者B 收到了: 今天的天气是晴天 sub.delete(observer1) ``` #### 发布订阅者模式 - 发布/订阅(Publish–subscribe pattern)是一种消息范式,消息的 `发送者` (称为发布者)不会将消息直接发送给特定的 `接收者` (称为订阅者)。 - 而是将发布的消息分为不同的类别,无需了解哪些订阅者(如果有的话)可能存在。同样的,订阅者可以表达对一个或多个类别的兴趣,只接收感兴趣的消息,无需了解哪些发布者(如果有的话)存在。 - 可以看作一个为 `邮件系统` ,你可以作为 `订阅者` 订阅某个网站的通知,邮件系统在其中充当 `发布订阅中心` 的角色,而 `发布者` 则是你订阅的网站。 优点: - 解耦发布者和订阅者,使得系统更灵活,扩展性更好;支持多对多的关系,可以实现更复杂的消息通信。 缺点: - 引入了调度中心,可能会增加系统的复杂度;由于间接通信,调试和理解代码可能会稍微困难一些。 **具体实现** ```javascript title="调度中心" class Dep { constructor() { this.subscriptions = {} } subscribe(topic, callback) { if (!this.subscriptions[topic]) { this.subscriptions[topic] = [] } this.subscriptions[topic].push(callback) } unSubscribe(topic) { if (!this.subscriptions[topic]) { return } delete this.subscriptions[topic] } publish(topic, data) { if (!this.subscriptions[topic]) { return } this.subscriptions[topic].forEach((callback) => { callback(data) }) } } ``` ```javascript title="发布者" class Publisher { constructor(pub) { this.pub = pub } publishMessage(topic, message) { this.pub.publish(topic, message) } } ``` ```javascript title="订阅者" class Subscriber { constructor(sub, name) { this.sub = sub this.name = name } subscribeToTopic(topic) { this.sub.subscribe(topic, (data) => { console.log(`订阅者 ${this.name} 收到${topic}消息: ${data}`) }) } unSubscribeToTopic(topic) { this.sub.unSubscribe(topic, (data) => { console.log(`订阅者 ${this.name} 取消订阅${topic}消息: ${data}`) }) } } ``` **具体使用** ```javascript title="一个栗子🌰" const dep = new Dep() const publisher = new Publisher(dep) const subscriber1 = new Subscriber(dep, 'A') const subscriber2 = new Subscriber(dep, 'B') subscriber1.subscribeToTopic('news') subscriber2.subscribeToTopic('weather') publisher.publishMessage('news', '一条新闻') // 订阅者 A 收到news消息: 一条新闻 publisher.publishMessage('weather', '今天的天气是晴天') // 订阅者 B 收到weather消息: 今天的天气是晴天 subscriber1.unSubscribeToTopic('news') ```


沪ICP备19023445号-2号
友情链接