2026年5月27日 00:59
发布订阅者模式和观察者模式的区别是什么?
观察者模式是主题直接通知观察者,发布订阅模式是通过消息代理中转。这是两者最根本的区别。
打个比方:观察者模式像是你直接打电话通知朋友"我搬家了"——你得知道每个人的号码。发布订阅模式像是你在朋友圈发了一条动态——你不需要知道谁在看,想看的人自然会收到推送。
代码层面,观察者模式里 Subject 维护一个 Observer 列表,状态变化时逐个调用 observer.update()。发布订阅模式多了一层 EventBus,publisher.emit(event) 和 subscriber.on(event) 互相不知道对方存在。
追问
为什么说观察者模式是同步的,发布订阅是异步的?
不是绝对的,但典型实现确实如此。观察者模式里 Subject.notify() 直接遍历调用回调,默认同步执行。发布订阅的 EventBus 可以把回调放进微任务队列或 setTimeout,天然支持异步。不过你也可以让观察者异步回调,只是设计意图不同。
实际项目中分别用在什么场景?
- 观察者模式:Vue 的响应式系统(Dep → Watcher)、React 的 useState 通知、MobX 的 observer
- 发布订阅:Vue 的 emit/on 事件总线、Node.js EventEmitter、Redis Pub/Sub、消息队列
两者可以互相替代吗?
简单场景可以用观察者替代发布订阅——比如小项目里直接用 Vue 的 emit 就够。但跨组件、跨模块、甚至跨服务的通信,发布订阅的消息代理解耦优势会很明显。反过来,如果只是两个对象的联动,多加一层 EventBus 反而过度设计了。
在面试中应该怎么回答这个区别?
先一句话说本质区别(是否经过中介),再用一个比喻让人秒懂,最后补充代码层面的差异(是否有 EventBus、是否知道对方存在)。加分项是举一个真实项目的例子,比如"我们在 XX 项目中用 EventEmitter 解耦了 A 模块和 B 模块的通信"。