新闻中心
如何使用Golang实现中介者模式解耦复杂交互_Golang 中介者模式实践技巧
中介者模式通过引入中介者封装对象间交互,降低系统耦合度。在Golang中利用接口和组合实现,如聊天室示例中用户通过ChatRoom通信,避免直接引用,提升可维护性,适用于GUI联动、微服务协调等场景。

在复杂的系统中,多个对象之间直接通信会导致代码高度耦合、难以维护。中介者模式通过引入一个“中介者”来封装对象之间的交互逻辑,让对象不再互相引用,而是通过中介者进行通信。Golang 虽然没有类和继承,但凭借接口和组合机制,可以非常优雅地实现中介者模式。
什么是中介者模式
中介者模式(Mediator Pattern)是一种行为设计模式,用于减少多个对象或组件之间的直接依赖。它将原本分散在多个对象中的交互逻辑集中到一个中介者对象中,从而降低系统的耦合度,提升可维护性。
典型应用场景包括:聊天室消息转发、GUI 组件联动、微服务间协调等。
使用接口定义组件与中介者
在 Golang 中,我们通过接口来定义组件和中介者的行为契约,确保松耦合。
示例:模拟聊天室中用户之间的消息传递定义 Colleague(同事)接口:
type User interface {
Send(message string)
Receive(message, from string)
SetName(name string)
GetName() string
SetChatRoom(room ChatRoom)
}
定义 Mediator(中介者)接口:
type ChatRoom interface {
Register(user User)
Send(from, to, message string)
}
这样,所有用户只需知道中介者的存在,而不需要了解其他用户的细节。
实现具体的中介者和用户
接下来实现一个具体的聊天室作为中介者:
Zyro AI Background Remover
Zyro推出的AI图片背景移除工具
145
查看详情
type SimpleChatRoom struct {
users map[string]User
}
func NewSimpleChatRoom() *SimpleChatRoom {
return &SimpleChatRoom{
users: make(map[string]User),
}
}
func (c *SimpleChatRoom) Register(user User) {
user.SetChatRoom(c)
c.users[user.GetName()] = user
c.Broadcast("system", fmt.Sprintf("%s 加入了聊天室", user.GetName()))
}
func (c *SimpleChatRoom) Send(from, to, message string) {
if to == "" {
c.Broadcast(from, message)
return
}
if user, exists := c.users[to]; exists {
user.Receive(message, from)
} else {
fmt.Printf("[系统] 用户 %s 不存在\n", to)
}
}
func (c *SimpleChatRoom) Broadcast(from, message string) {
for _, user := range c.users {
if user.GetName() != from {
user.Receive(message, from)
}
}
}
再实现一个具体用户:
type ChatUser struct {
name string
chatRoom ChatRoom
}
func NewChatUser(name string) *ChatUser {
return &ChatUser{name: name}
}
func (u *ChatUser) SetChatRoom(room ChatRoom) {
u.chatRoom = room
}
func (u *ChatUser) Send(message string) {
if u.chatRoom != nil {
u.chatRoom.Send(u.name, "", message) // 群发
}
}
func (u *ChatUser) SendTo(to, message string) {
if u.chatRoom != nil {
u.chatRoom.Send(u.name, to, message) // 私聊
}
}
func (u *ChatUser) Receive(message, from string) {
fmt.Printf("[%s] 收到来自 %s 的消息: %s\n", u.name, from, message)
}
func (u *ChatUser) SetName(name string) {
oldName := u.name
u.name = name
if u.chatRoom != nil {
// 可通知系统用户名变更
}
}
func (u *ChatUser) GetName() string {
return u.name
}
实际使用示例
现在我们可以轻松地构建一个解耦的聊天系统:
func main() {
chatRoom := NewSimpleChatRoom()
alice := NewChatUser("Alice")
bob := NewChatUser("Bob")
charlie := NewChatUser("Charlie")
chatRoom.Register(alice)
chatRoom.Register(bob)
chatRoom.Register(charlie)
alice.Send("大家好!")
bob.SendTo("Charlie", "嘿,晚上一起写代码吗?")
charlie.Send("没问题!")
}
输出结果:
[系统] Alice 加入了聊天室 [系统] Bob 加入了聊天室 [系统] Charlie 加入了聊天室 [Bob] 收到来自 Alice 的消息: 大家好! [Charlie] 收到来自 Alice 的消息: 大家好! [Charlie] 收到来自 Bob 的消息: 嘿,晚上一起写代码吗? [Alice] 收到来自 Charlie 的消息: 没问题! [Bob] 收到来自 Charlie 的消息: 没问题!
可以看到,每个用户无需持有其他用户的引用,所有通信都由 ChatRoom 统一调度。
实践技巧与注意事项
在 Golang 中使用中介者模式时,有几个关键点能提升代码质量:
- 优先使用接口而非具体类型:让组件依赖抽象,便于替换和测试。
- 避免中介者变成上帝对象:中介者应只负责协调,不处理业务逻辑。复杂逻辑应下沉到组件内部。
-
考虑并发安全:如果多个 goroutin
e 同时发送消息,需对共享状态(如 users map)加锁。 - 支持动态注册/注销:允许组件在运行时加入或退出,增强灵活性。
- 可扩展消息类型:可引入消息结构体替代字符串,携带更多元数据(时间戳、类型、附件等)。
基本上就这些。中介者模式在 Golang 中虽无显式类支持,但借助接口和结构体组合,依然能清晰表达设计意图,有效解耦复杂交互场景。关键是控制职责边界,保持中介逻辑简洁。不复杂但容易忽略。
以上就是如何使用Golang实现中介者模式解耦复杂交互_Golang 中介者模式实践技巧的详细内容,更多请关注其它相关文章!
# golang
# ai
# 聊天室
# 多个
# 大家好
# 如何使用
# 象中
# 晚上
# go
# 教育行业的营销推广案例
# 网站推广策划活动怎么选
# 关键词排名17是第几页
# 株洲SEO优化价格
# 中山外贸推广营销公司有哪些
# 重庆seo服务外包
# 哈密地抖音关键词排名
# 吕梁网站推广代运营
# seo推广精通火星推荐
# 福州网站建设价格最优
# 我们可以
# 适用于
# 只需
# 是一种
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
动漫共和国防屏蔽稳定域名-动漫共和国官方正版直达通道
J*a最大堆Heapify方法修复:索引计算与边界条件深度解析
如何创建独立于主系统的J*a运行环境_隔离式环境搭建策略
BetterDiscord插件中安全更新用户简介的实践指南
QQ邮箱登录官网首页 腾讯QQ邮箱网页入口
AWS EC2实例间SQL Server连接超时:安全组配置与故障排除指南
Linux如何排查内存不足OOME问题_LinuxOOM分析教程
J*aScript数据结构转换:将对象数组按类别分组
深入理解J*a编译器的兼容性选项:从-source到--release
Win10如何开启蓝牙功能_Windows10找不到蓝牙开关解决方法
《北京人工智能产业白皮书(2025)》发布:全年核心产值预计突破 4500 亿元
Win11怎么关闭触摸屏_Windows 11禁用HID符合标准触摸屏
QQ邮箱登录平台入口 QQ邮箱网页版邮箱官方入口
Surface怎么安装系统 微软Surface Pro U盘重装win11教程
Win11如何使用Windows Sandbox Win11沙盒功能开启与使用教程【详解】
Win11如何开启讲述人功能 Win11屏幕阅读器(讲述人)开启与关闭【教程】
Node.js CSV 数据处理:基于字段值条件过滤整条记录的策略
字由网在线版登录地址 字由网网页版安全入口
深入理解Google Cloud Datastore查询:祖先路径与数据一致性
win11如何卸载Windows更新补丁 Win11解决更新导致系统不稳定的问题【修复】
妖精动漫免费平台 妖精动漫官网资源观看网址
漫蛙2(台版)官方入口地址 漫蛙2(台版)正版漫画网页端
蛙漫官网漫画入口地址_蛙漫在线畅读无广告弹窗
AO3访问入口汇总 AO3网页版同人作品一键直达
Angular中单选按钮的正确使用与常见陷阱解析
地铁跑酷免费秒玩入口链接 地铁跑酷小游戏免费秒玩网站
163邮箱登录密码 163邮箱忘记密码找回
如何在 Windows 11 中启动游戏手柄设置
打开就能玩的植物大战僵尸 植物大战僵尸网页版传送门
163邮箱网页版入口导航平台 163邮箱网页版登录入口官网导航
Win11怎么修改默认浏览器_Windows 11设置Chrome为默认
J*a里如何使用forEach遍历Map_Map遍历方法说明
微信群消息显示延迟如何解决 微信群消息刷新优化方法
uc浏览器网页版极速入口 uc网页浏览器网页版流畅体验
自定义Bag-of-Words实现:处理带负号的词汇权重
如何在CSS中使用visited与link控制链接颜色_visited link伪类配合
新手怎么开始学化妆 零基础化妆入门教程
Win11怎么查看电脑配置_Win11硬件配置检测工具使用
html网页设计源代码怎么运行_运行html网页设计源代码步骤【指南】
Win10自动更新怎么关闭 Win10永久关闭系统更新的两种方法【终极版】
Golang如何使用bytes.Split分割字节切片_Golang bytes切片分割方法
C++20的source_location是什么_C++在编译期获取源码位置信息用于日志和断言
Centos/Linux 系统下安装 composer 的完整步骤
Golang切片为何属于引用类型_Golang slice底层结构与引用语义说明
《噬血代码2》新预告片发布 展示游戏剧情
Pandas DataFrame 高效批量赋值:告别循环与笛卡尔积误区
整合Supabase认证与Django模型:跨模式迁移的解决方案
处理Kafka消费者会话超时:深入理解消息处理语义与幂等性
铁路12306的积分有效期是多久_铁路12306积分有效期说明
Golang如何实现状态模式管理对象状态_Golang State模式实现技巧


2025-11-15
浏览次数:次
返回列表
e 同时发送消息,需对共享状态(如 users map)加锁。