Go语言中实现观察者模式有四种常见方式:1. 基于接口的标准模式,通过Subject和Observer接口实现松耦合;2. 使用channel实现异步通知,利用goroutine和channel进行非阻塞消息广播;3. 利用闭包简化观察者,以函数类型封装更新逻辑;4. 泛型支持的通用模式(Go 1.18+),可传递任意类型数据。选择方式需根据场景:标准接口适合结构清晰的系统,channel适合高并发,闭包适合轻量逻辑,泛型适合多类型数据传递。关键在于解耦主题与观察者,并注意并发安全与注销时的切片操作安全。
在Go语言中实现观察者模式,核心是定义一个主题(Subject)和多个观察者(Observer),当主题状态发生变化时,自动通知所有注册的观察者。这种设计模式常用于事件处理系统、消息订阅等场景。以下是几种常见的Golang实现方式。
通过接口定义主题和观察者的行为,实现松耦合结构。
定义观察者和主题接口:
type Observer interface {
Update(message string)
}
type Subject interface {
Register(observer Observer)
Deregister(observer Observer)
Notify(message string)
}
实现具体主题:
type ConcreteSubject struct {
observers []Observer
}
func (s *ConcreteSubject) Register(observer Observer) {
s.observers = append(s.observers, observer)
}
func (s *ConcreteSubject) Deregister(observer Observer) {
for i, obs := range s.observers {
if obs == observer {
s.observers = append(s.observers[:i], s.observers[i+1:]...)
break
}
}
}
func (s *ConcreteSubject) Notify(message string) {
for _, observer := range s.observers {
observer.Update(message)
}
}
实现具体观察者:
type ConcreteObserver struct {
name string
}
func (o *ConcreteObserver) Update(message string) {
fmt.Printf("[%s] 收到消息: %s\n", o.name, message)
}
使用示例:
subject := &ConcreteSubject{}
observerA := &ConcreteObserver{name: "A"}
observerB := &ConcreteObserver{name: "B"}
subject.Register(observerA)
subject.Register(observerB)
subject.Notify("系统更新了")
// 输出:
// [A] 收到消息: 系统更新了
// [B] 收到消息: 系统更新了
利用Go的并发特性,通过channel实现非阻塞的消息广播,适合高并发场景。
type AsyncSubject struct {
register chan Observer
deregister chan Observer
message chan string
observers map[Observer]bool
}
func NewAsyncSubject() *AsyncSubject {
subject := &AsyncSubject{
register: make(chan Observer),
deregister: make(chan Observer),
message: make(chan string),
observers: make(map[Observer]bool),
}
go subject.start()
return subject
}
func (s *AsyncSubject) start() {
for {
select {
case observer := <-s.register:
s.observers[observer] = true
case observer := <-s.deregister:
delete(s.observers, observer)
case msg := <-s.message:
for observer := range s.observers {
go observer.Update(msg) // 异步通知
}
}
}
}
func (s *AsyncSubject) Register(observer Observer) {
s.register <- observer
}
func (s *AsyncSubject) Deregister(observer Observer) {
s.deregister <- observer
}
func (s *AsyncSubject) Notify(message string) {
s.message <- message
}
这种方式将注册、注销和通知操作放入goroutine中处理,避免主线程阻塞。
如果不需要复杂的结构体,可以用函数类型和闭包快速实现轻量级观察者。
type Callback func(message string)type FuncObserver struct { callback Callback }
func (f *FuncObserver) Update(message string) { f.callback(message) }
// 使用示例 observer := &FuncObserver{ callback: func(msg string) { fmt.Println("闭包收到:", msg) }, }
这种方式适合逻辑简单的监听场景,代码更简洁。
使用泛型可以让观察者模式支持不同类型的数据传递。
type GenericObserver[T any] interface {
OnEvent(data T)
}
type GenericSubject[T any] struct {
observers []GenericObserver[T]
}
func (s *GenericSubject[T]) Attach(obs GenericObserver[T]) {
s.observers = append(s.observers, obs)
}
func (s *GenericSubject[T]) Notify(data T) {
for _, obs := range s.observers {
obs.OnEvent(data)
}
}
可以用于传递结构体、数字等任意类型数据。
基本上就这些常见实现方式。选择哪种取决于你的需求:标准接口适合清晰结构,channel适合高并发,闭包适合轻量逻辑,泛型适合类型多样的场景。关键是理解主题与观察者之间的解耦关系。不复杂但容易忽略细节,比如注销时的切片操作安全性和并发访问控制。实际项目中建议结合sync.Mutex保护共享状态。
# go
# golang
# go语言
# app
# 并发访问
# 封装
# 结构体
# 接口
# 泛型
# 线程
# 主线程
相关文章:
武汉外贸网站制作公司,现在武汉外贸前景怎么样啊?
PHP正则匹配日期和时间(时间戳转换)的实例代码
如何通过IIS搭建网站并配置访问权限?
c# Task.Yield 的作用是什么 它和Task.Delay(1)有区别吗
C++用Dijkstra(迪杰斯特拉)算法求最短路径
外贸公司网站制作,外贸网站建设一般有哪些步骤?
建站之星logo尺寸如何设置最合适?
如何在阿里云域名上完成建站全流程?
成都响应式网站开发,dw怎么把手机适应页面变成网页?
如何访问已购建站主机并解决登录问题?
手机怎么制作网站教程步骤,手机怎么做自己的网页链接?
北京网页设计制作网站有哪些,继续教育自动播放怎么设置?
北京制作网站的公司,北京铁路集团官方网站?
如何配置WinSCP新建站点的密钥验证步骤?
公司网站设计制作厂家,怎么创建自己的一个网站?
如何高效搭建专业期货交易平台网站?
企业网站制作费用多少,企业网站空间一般需要多大,费用是多少?
如何做静态网页,sublimetext3.0制作静态网页?
山东云建站价格为何差异显著?
建站之星各版本价格是多少?
青岛网站建设如何选择本地服务器?
已有域名和空间如何搭建网站?
如何通过宝塔面板实现本地网站访问?
建站IDE高效指南:快速搭建+SEO优化+自适应模板全解析
威客平台建站流程解析:高效搭建教程与设计优化方案
,网页ppt怎么弄成自己的ppt?
宝塔面板如何快速创建新站点?
建站之星3.0如何解决常见操作问题?
武汉网站设计制作公司,武汉有哪些比较大的同城网站或论坛,就是里面都是武汉人的?
建站之星后台密码如何安全设置与找回?
微信小程序 五星评分(包括半颗星评分)实例代码
公众号网站制作网页,微信公众号怎么制作?
代购小票制作网站有哪些,购物小票的简要说明?
高防服务器租用如何选择配置与防御等级?
内部网站制作流程,如何建立公司内部网站?
惠州网站建设制作推广,惠州市华视达文化传媒有限公司怎么样?
如何选择网络建站服务器?高效建站必看指南
教程网站设计制作软件,怎么创建自己的一个网站?
设计网站制作公司有哪些,制作网页教程?
建站之星安装步骤有哪些常见问题?
如何挑选最适合建站的高性能VPS主机?
建站之星后台密码遗忘如何找回?
如何快速搭建高效简练网站?
网页设计与网站制作内容,怎样注册网站?
javascript中对象的定义、使用以及对象和原型链操作小结
建站之星备案流程有哪些注意事项?
建站之星安装需要哪些步骤及注意事项?
如何用5美元大硬盘VPS安全高效搭建个人网站?
标准网站视频模板制作软件,现在有哪个网站的视频编辑素材最齐全的,背景音乐、音效等?
免费制作小说封面的网站有哪些,怎么接网站批量的封面单?
*请认真填写需求信息,我们会在24小时内与您取得联系。