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

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

基本结构设计
要实现观察者模式,需要定义几个核心组件:
Subject(主题):负责管理观察者列表,并在状态变化时通知它们。Observer(观察者):接收通知并作出响应。Event(事件):可选,用于封装通知内容。
用 Go 来实现的话,可以将 Subject 看作一个包含 channel 的结构体,每个 Observer 是一个监听该 channel 的 goroutine。
立即学习“go语言免费学习笔记(深入)”;

type Event stringtype Observer chan Eventtype Subject struct { observers []Observer}
这样每个 Observer 都是一个接收 Event 的 channel。
注册和通知机制
注册观察者的过程其实就是把 Observer 添加到 Subject 的列表中。而通知就是遍历这些 Observer 并发送事件。

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
微信扫一扫
支付宝扫一扫