返回

钩沉:观察者与发布者-订阅者的两三事

前端

最近在阅读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中,发布者-订阅者模式被广泛用于组件之间的通信。