怎样用Golang实现观察者模式 使用channel和goroutine的优雅方案

观察者模式在 go 中通过 channel 和 goroutine 实现,核心组件包括 subject、observer 和 event。1. subject 管理观察者列表并在状态变化时通知它们;2. observer 是监听 channel 的 goroutine,接收事件并处理;3. event 用于封装通知内容。注册观察者即将其加入 subject 列表,通知则通过遍历列表发送事件,并使用 goroutine 并发执行以避免阻塞。为支持反馈,可使用结构体代替简单事件。每个观察者持续监听 channel,处理事件时可结合业务逻辑。程序退出时应关闭 channel 并回收 goroutine,防止泄漏,可通过维护 done channel 实现优雅关闭。这种方式轻量且易扩展,符合 go 的并发模型。

怎样用Golang实现观察者模式 使用channel和goroutine的优雅方案

观察者模式的核心在于“事件通知”,当某个对象状态发生变化时,所有依赖它的对象都会被自动通知。在 Go 语言中,使用 channel 和 goroutine 实现这一模式既高效又简洁。

怎样用Golang实现观察者模式 使用channel和goroutine的优雅方案

基本结构设计

要实现观察者模式,需要定义几个核心组件:

Subject(主题):负责管理观察者列表,并在状态变化时通知它们。Observer(观察者):接收通知并作出响应。Event(事件):可选,用于封装通知内容。

用 Go 来实现的话,可以将 Subject 看作一个包含 channel 的结构体,每个 Observer 是一个监听该 channel 的 goroutine。

立即学习“go语言免费学习笔记(深入)”;

怎样用Golang实现观察者模式 使用channel和goroutine的优雅方案

type Event stringtype Observer chan Eventtype Subject struct {    observers []Observer}

这样每个 Observer 都是一个接收 Event 的 channel。

注册和通知机制

注册观察者的过程其实就是把 Observer 添加到 Subject 的列表中。而通知就是遍历这些 Observer 并发送事件。

怎样用Golang实现观察者模式 使用channel和goroutine的优雅方案

func (s *Subject) Register(obs Observer) {    s.observers = append(s.observers, obs)}func (s *Subject) Notify(event Event) {    for _, obs := range s.observers {        go func(o Observer) {            o <- event        }(obs)    }}

这里用了 go func(...) 包裹发送操作,确保每个通知都在独立的 goroutine 中执行,避免阻塞主线程。

小技巧:如果你希望观察者处理完事件后能反馈结果,可以在 Observer channel 中使用结构体而不是简单字符串,比如:type Response struct { Success bool Msg string}type Observer chan struct { Event Event Response chan Response}

观察者的启动与处理

每个观察者本质上是一个运行中的 goroutine,持续监听来自 channel 的事件:

func StartObserver(id string) Observer {    obs := make(Observer)    go func() {        for event := range obs {            fmt.Printf("Observer %s received event: %sn", id, event)            // 处理逻辑        }    }()    return obs}

你可以创建多个这样的观察者,并注册到 Subject 上。

完整使用示例:

subject := &Subject{}observer1 := StartObserver("A")observer2 := StartObserver("B")subject.Register(observer1)subject.Register(observer2)subject.Notify("system:reboot")

这样就能看到两个观察者各自收到通知并打印信息了。

优雅关闭和资源回收

如果程序是长期运行的服务,要注意对 Observer channel 的关闭,避免 goroutine 泄漏。

一种做法是在 Subject 中维护一个 done channel,在清理时关闭所有 Observer:

type Subject struct {    observers []Observer    done      chan struct{}}func (s *Subject) Stop() {    close(s.done)    for _, obs := range s.observers {        close(chan obs)    }}

然后在观察者的循环中监听 done 信号:

go func() {    for {        select {        case event := <-obs:            // handle event        case <-s.done:            return        }    }}()

这样就能安全退出所有 goroutine。

基本上就这些。这种基于 channel 和 goroutine 的方式非常符合 Go 的并发模型,也足够轻量、易扩展。只要注意好 channel 的生命周期和 goroutine 的回收,就是一个很实用的观察者实现方案。

以上就是怎样用Golang实现观察者模式 使用channel和goroutine的优雅方案的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1395816.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月15日 13:01:27
下一篇 2025年12月15日 13:11:12

相关推荐

发表回复

登录后才能评论
关注微信