钩沉:观察者与发布者-订阅者的两三事
2023-12-17 10:22:27
最近在阅读Vue源码的时候,发现自己对观察者以及发布者-订阅者模式的理解不够,因此记录一下自己的思路。
有人认为观察者模式和发布者-订阅者模式是等同的,也有人觉得两者存在一些区别。其实两者的确有一些区别,但目的都是为了解决相同的问题:实现对象之间的松散耦合。
观察者模式
观察者模式是一种软件设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某个主题对象。当主题对象的状态发生变化时,所有观察者对象都会收到通知,并自动更新自己的状态。
在观察者模式中,主题对象和观察者对象之间是松散耦合的。主题对象只需要知道自己有哪些观察者对象,而不需要知道观察者对象的具体实现。观察者对象只需要知道自己订阅了哪些主题对象,而不需要知道主题对象的具体实现。
发布者-订阅者模式
发布者-订阅者模式也是一种软件设计模式,它也是为了实现对象之间的松散耦合。发布者对象将消息发布到频道,订阅者对象订阅这些频道并监听消息。当发布者对象发布消息时,所有订阅了该频道的订阅者对象都会收到消息,并自动更新自己的状态。
在发布者-订阅者模式中,发布者对象和订阅者对象之间也是松散耦合的。发布者对象只需要知道自己发布了哪些消息,而不需要知道订阅者对象的具体实现。订阅者对象只需要知道自己订阅了哪些频道,而不需要知道发布者对象的具体实现。
两者区别
观察者模式和发布者-订阅者模式之间的主要区别在于:
- 在观察者模式中,主题对象知道所有的观察者对象,而发布者对象不知道订阅者对象。
- 在观察者模式中,观察者对象只能监听一个主题对象,而订阅者对象可以订阅多个频道。
在Vue中的应用
Vue是一个前端JavaScript框架,它使用了发布者-订阅者模式来实现组件之间的通信。在Vue中,组件可以通过on()方法订阅其他组件发出的事件,通过emit()方法发布事件。
例如,以下代码演示了如何在Vue中使用发布者-订阅者模式:
// 组件A
export default {
data() {
return {
count: 0
}
},
methods: {
incrementCount() {
this.count++
this.$emit('count-changed', this.count)
}
}
}
// 组件B
export default {
data() {
return {
count: 0
}
},
created() {
this.$on('count-changed', (count) => {
this.count = count
})
}
}
在上面的代码中,组件A是一个发布者对象,它通过emit()方法发布了'count-changed'事件。组件B是一个订阅者对象,它通过on()方法订阅了'count-changed'事件。当组件A调用incrementCount()方法时,组件B的count数据会自动更新。
总结
观察者模式和发布者-订阅者模式都是为了解决相同的问题:实现对象之间的松散耦合。两者之间存在一些区别,但在实际应用中,它们经常被混淆使用。在Vue中,发布者-订阅者模式被广泛用于组件之间的通信。