常见模式之五:发布订阅模式
定义
顾名思义,就是有个发布者,和多个订阅者,发布者发布一条消息,订阅者都能收到并行处理
使用场景
-
适用于需要解耦、并发处理和可扩展性的场景
-
提供了一种灵活的机制,允许多个订阅者独立地处理事件或消息
-
比如事件驱动系统、消息队列等等
示例
假设有个场景:我们支付完成后,需要做三件事
-
更新订单状态
-
发送站内信
-
更新商品销量
代码如下:
Go
package main
import (
"fmt"
"sync"
)
// EventData 发布数据
type EventData struct {
Data interface{}
}
// Subscriber 关注者
type Subscriber struct {
UniqueFlag string
HandleFunc func(EventData)
}
// Publisher 发布者
type Publisher struct {
SubDict map[string]*Subscriber
mutex *sync.Mutex
}
// NewPublisher 初始化发布者
func NewPublisher() *Publisher {
return &Publisher{
SubDict: make(map[string]*Subscriber),
mutex: &sync.Mutex{},
}
}
// AddSubscriber 添加订阅
func (p *Publisher) AddSubscriber(s *Subscriber) {
p.mutex.Lock()
defer p.mutex.Unlock()
p.SubDict[s.UniqueFlag] = s
}
// DelSubscriber 移除订阅
func (p *Publisher) DelSubscriber(s *Subscriber) {
p.mutex.Lock()
defer p.mutex.Unlock()
delete(p.SubDict, s.UniqueFlag)
}
// Publish 发布消息
func (p *Publisher) Publish(ed EventData) {
p.mutex.Lock()
defer p.mutex.Unlock()
wg := &sync.WaitGroup{}
for _, s := range p.SubDict {
wg.Add(1)
go func(sub *Subscriber) {
defer wg.Done()
sub.HandleFunc(ed)
}(s)
}
wg.Wait()
}
func main() {
p := NewPublisher()
// 调用支付后
// 1.更改订单状态
// 2.发送站内信
// 3.商品销售量+1
p.AddSubscriber(
&Subscriber{
UniqueFlag: "orderUpdate",
HandleFunc: func(data EventData) {
fmt.Println("更改订单状态 ", data)
},
})
p.AddSubscriber(
&Subscriber{
UniqueFlag: "msgSend",
HandleFunc: func(data EventData) {
fmt.Println("发送站内信 ", data)
},
})
p.AddSubscriber(
&Subscriber{
UniqueFlag: "saleUpdate",
HandleFunc: func(data EventData) {
fmt.Println("商品销售量+1 ", data)
},
})
p.Publish(EventData{
Data: struct {
SaleId int
UserId int
SaleName string
}{
SaleId: 123,
UserId: 456,
SaleName: "华为meta60pro",
},
})
}
打印结果:
发送站内信 {{123 456 华为meta60pro}}
商品销售量+1 {{123 456 华为meta60pro}}
更改订单状态 {{123 456 华为meta60pro}}