观察者和发布订阅者模式

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

  • 使用示例
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 方法),观察者也需要知道主题的存在。
      • 适用场景:适用于对象之间的关系相对固定且已知的情况
    • 发布订阅模式
      • 耦合度较低:发布者和订阅者之间通过事件通道进行通信,彼此不需要直接知道对方的存在。
      • 适用场景:适用于需要高度解耦的系统,特别是在大型系统中,组件之间的依赖关系复杂时。
  • 灵活性
    • 观察者模式
      • 灵活性有限:主题和观察者之间的关系是固定的,难以动态地添加或移除观察者。
      • 适用场景:适用于简单的、关系固定的场景。
    • 发布订阅模式
      • 灵活性高:可以动态地添加或移除订阅者,事件通道可以处理多种类型的事件。
      • 适用场景:适用于复杂的、需要动态管理的系统。
相关推荐
1024小神28 分钟前
在GitHub action中使用添加项目中配置文件的值为环境变量
前端·javascript
齐尹秦37 分钟前
CSS 列表样式学习笔记
前端
Mnxj41 分钟前
渐变边框设计
前端
用户76787977373243 分钟前
由Umi升级到Next方案
前端·next.js
快乐的小前端1 小时前
TypeScript基础一
前端
北凉温华1 小时前
UniApp项目中的多服务环境配置与跨域代理实现
前端
源柒1 小时前
Vue3与Vite构建高性能记账应用 - LedgerX架构解析
前端
Danny_FD1 小时前
常用 Git 命令详解
前端·github
stanny1 小时前
MCP(上)——function call 是什么
前端·mcp
1024小神1 小时前
GitHub action中的 jq 是什么? 常用方法有哪些
前端·javascript