观察者和发布订阅者模式

尽管观察者模式和发布订阅模式在某些方面相似,但它们在设计和使用上有一些关键的区别。以下是详细的对比:

  • 使用示例
javascript 复制代码
//观察者模式
class Subject { 
    constructor() { 
        this.observers = []; 
    } 
    addObserver(observer) { 
        this.observers.push(observer); 
    } 
    removeObserver(observer) { 
        this.observers = this.observers.filter((obs) => obs !== observer); 
    } 
    notify(data) { 
        this.observers.forEach((observer) => observer.update(data)); 
    } 
} 

class Observer { 
    constructor(name) { 
        this.name = name; 
    } 
    update(data) { 
        console.log(`${this.name} received data: ${data}`); 
    } 
} 

const subject = new Subject(); 
const observer1 = new Observer('Observer 1'); 
const observer2 = new Observer('Observer 2'); 
subject.addObserver(observer1); 
subject.addObserver(observer2); 
subject.notify('Hello Observers!'); 
// 输出: Observer 1 received data: Hello Observers! 
// Observer 2 received data: Hello Observers!
js 复制代码
//发布订阅模式
class EventEmitter { 
    constructor() { 
        this.events = {}; 
    } 
    subscribe(eventName, callback) { 
        if (!this.events[eventName]) { 
            this.events[eventName] = []; 
        } 
        this.events[eventName].push(callback);
    } 
    unsubscribe(eventName, callback) { 
        if (this.events[eventName]) { 
            this.events[eventName] = this.events[eventName].filter( (cb) => cb !== callback ); 
        } 
    } 
    publish(eventName, ...args) { 
        if (this.events[eventName]) { 
            this.events[eventName].forEach((callback) => { callback(...args); });
        }
    }
} 
const ee = new EventEmitter(); 
ee.subscribe('click', (arg) => { 
    console.log('click1' + arg); 
}); 
ee.publish('click', 121212); // 输出: click1121212   
  • 定义和角色
    • 观察者模式
      • 核心角色:

        Subject(主题):维护一个观察者列表,提供添加、删除观察者的方法,并在状态变化时通知所有观察者。

        Observer(观察者):定义一个更新接口,当主题状态变化时,观察者通过该接口接收通知并进行相应处理

      • 关系

        观察者和主题之间存在直接的依赖关系。观察者需要知道主题的存在,并且主题需要知道观察者的具体接口

    • 发布订阅模式
      • 核心角色:

        Publisher(发布者):发布事件或消息,但不需要知道订阅者的存在。

        Subscriber(订阅者):订阅特定事件或消息,并在事件发生时接收通知。

        Event Channel(事件通道:作为发布者和订阅者之间的中介,负责事件的分发。

      • 关系

        发布者和订阅者之间没有直接的依赖关系。发布者只需知道如何通过事件通道发布事件,而订阅者只需知道如何订阅和处理事件。

  • 解耦成都
    • 观察者模式
      • 耦合度较高:主题需要知道观察者的具体接口(如 update 方法),观察者也需要知道主题的存在。
      • 适用场景:适用于对象之间的关系相对固定且已知的情况
    • 发布订阅模式
      • 耦合度较低:发布者和订阅者之间通过事件通道进行通信,彼此不需要直接知道对方的存在。
      • 适用场景:适用于需要高度解耦的系统,特别是在大型系统中,组件之间的依赖关系复杂时。
  • 灵活性
    • 观察者模式
      • 灵活性有限:主题和观察者之间的关系是固定的,难以动态地添加或移除观察者。
      • 适用场景:适用于简单的、关系固定的场景。
    • 发布订阅模式
      • 灵活性高:可以动态地添加或移除订阅者,事件通道可以处理多种类型的事件。
      • 适用场景:适用于复杂的、需要动态管理的系统。
相关推荐
橙子家7 小时前
浏览器缓存之【身份与会话管理】:Cookies 和 Private state tokens
前端
最新资讯动态8 小时前
HDC 2026 | 对话鲸鸿动能:存量时代,品牌如何夺回营销“主动权”?
前端
最新资讯动态8 小时前
游戏出海,从产品走向体系
前端
最新资讯动态8 小时前
20人团队跑出百万DAU、大厂也来抢量:谁在鸿蒙生态跑出加速度
前端
最新资讯动态8 小时前
千万开发者背后,鸿蒙商业化的B面
前端
爱勇宝10 小时前
AI 时代:智商决定起点,情商决定走多远
前端·ai编程
kyriewen10 小时前
用了半年 Claude Code 后,我尝试关掉它写了一周代码——结果比想象中严重
前端·javascript·ai编程
IT_陈寒11 小时前
Vite的静态资源打包让我熬夜到三点,这坑千万别跳
前端·人工智能·后端
徐小夕12 小时前
万字拆解 JitWord:企业级实时协同文档底层架构 + 大模型 AI 融合完整实践
前端·vue.js·github
一份执念12 小时前
uni-app 小程序分包限制处理与主包体积优化实战
前端·微信小程序