事件驱动架构是计算机科学中一种高度可扩展的范例。它允许我们可以多方系统异步处理事件。
事件总线是发布/订阅模式的实现,其中发布者发布数据,并且感兴趣的订阅者可以监听这些数据并基于这些数据作出处理。这使发布者与订阅者松耦合。发布者将数据事件发布到事件总线,总线负责将它们发送给订阅者。
传统的实现事件总线的方法会涉及到使用回调。订阅者通常实现接口,然后事件总线通过接口传播数据。
使用 Go 的并发模型,我们知道在大多数地方可以使用 channel
来替代回调。在本文中,我们将重点介绍如何使用 channel
来实现事件总线。
我们专注于 基于主题(topic)的事件。发布者发布到主题,订阅者可以收听它们。
定义数据结构
为了实现事件总线,我们需要定义要传递的数据结构。我们可以使用 struct
简单地创建一个新的数据类型。我们定义一个 DataEvent
的结构体如下:
type DataEvent struct {
Data interface{}
Topic string
}
在这里,我们已经将基础数据定义为接口,这意味着它可以是任何值。我们还将主题定义为结构的成员。订阅者可能会收听多个主题,因此,我们通过主题来让订阅者可以区分不同的事件的做法是不错的。
介绍 channels
现在我们已经为事件总线定义了我们主要的数据结构,我们还需要一种方法来传递它。为此,我们可以定义一个可以传播 DataEvent
的 DataChannel
类型。
// DataChannel 是一个能接收 DataEvent 的 channel
type DataChannel chan DataEvent
// DataChannelSlice 是一个包含 DataChannels 数据的切片
type DataChannelSlice [] DataChannel
DataChannelSlice
的创建是为了保留 DataChannel
的切片并轻松引用它们。
事件总线
// EventBus 存储有关订阅者感兴趣的特定主题的信息
type EventBus struct {
subscribers map[string]DataChannelSlice
rm sync.RWMutex
}
EventBus
有 subscribers
,这是一个包含 DataChannelSlices
的 map。我们使用互斥锁来保护并发访问的读写。
通过使用 map
和定义 topics
,它允许我们轻松地组织事件。主题被视为 map
的键。当有人发布它时,我们可以通过键轻松找到主题,然后将事件传播到