0

0

如何在Golang中实现中介者模式_Golang中介者模式设计与应用技巧

P粉602998670

P粉602998670

发布时间:2026-02-05 12:30:10

|

813人浏览过

|

来源于php中文网

原创

Go语言很少直接写传统中介者模式,因其无类继承和接口强制约束,硬套UML结构反而加重代码、降低可测性;真实项目多用组合+函数回调+通道解耦,如用func类型替代Mediator接口、chan实现事件分发,或直接字段嵌入,遵循“先具体后抽象”原则。

如何在golang中实现中介者模式_golang中介者模式设计与应用技巧

为什么 Go 语言里很少直接写传统中介者模式

Go 没有类继承、没有接口实现强制约束,也没有“对象引用传递”意义上的中心化对象注册表;硬套 UML 类图里的 Mediator 抽象类 + 多个 Colleague 子类结构,反而会让代码变重、难测、易耦合。真实项目中更常见的是用组合+函数回调+通道来解耦协作逻辑,而不是造一个“中介者实例”来管理所有同事。

func 类型和闭包替代 Mediator 接口

把中介逻辑抽象成可注入的函数,比定义一堆接口和实现更符合 Go 的惯用法。比如两个模块需要协同更新状态,与其让它们都依赖某个 Mediator 实例,不如由上层统一传入回调:

// 定义协作行为:当 A 发生变更时,通知 B 做什么
type OnAUpdate func(aValue string)

// A 模块只关心自己能触发什么,不关心谁响应 type ModuleA struct { onUpdate OnAUpdate }

func (a *ModuleA) TriggerChange(val string) { if a.onUpdate != nil { a.onUpdate(val) } }

// B 模块接收通知并执行本地逻辑 type ModuleB struct { lastSeen string }

func (b *ModuleB) HandleAUpdate(val string) { b.lastSeen = val }

  • 避免了全局单例或构造时强依赖 Mediator 实例
  • OnAUpdate 可以是普通函数、方法值、甚至带状态的闭包
  • 单元测试时可轻松 mock 行为,无需模拟整个中介者生命周期

chan 实现松耦合事件分发(适合跨 goroutine 场景)

当协作涉及异步、并发或跨组件边界(如 HTTP handler 和后台 worker),用通道比函数回调更自然:

// 中介者退化为一个事件总线:只负责转发,不持有业务逻辑
type EventBroker struct {
    events chan Event
}

type Event struct { Type string Data interface{} }

func NewEventBroker() *EventBroker { return &EventBroker{ events: make(chan Event, 100), // 缓冲防阻塞 } }

// 各模块只订阅自己关心的 Type,不互相 import func (e *EventBroker) Publish(evt Event) { select { case e.events <- evt: default: // 队列满时丢弃或打日志,不 panic } }

  • 发布者完全不知道谁消费,消费者也无需知道谁发布
  • 注意缓冲区大小和背压处理,否则 chan 满会导致协程卡死
  • 别在 Publish 里做耗时操作,否则拖慢所有发布方

什么时候该放弃“模式思维”,直接用结构体字段组合

很多所谓“中介需求”,其实只是两个结构体需要共享少量状态或触发简单动作——这时候最直白的方式就是把对方作为字段嵌入:

《PHP设计模式指南》中文版
《PHP设计模式指南》中文版

《PHP设计模式》首先介绍了设计模式,讲述了设计模式的使用及重要性,并且详细说明了应用设计模式的场合。接下来,本书通过代码示例介绍了许多设计模式。最后,本书通过全面深入的案例分析说明了如何使用设计模式来计划新的应用程序,如何采用PHP语言编写这些模式,以及如何使用书中介绍的设计模式修正和重构已有的代码块。作者采用专业的、便于使用的格式来介绍相关的概念,自学成才的编程人员与经过更多正规培训的编程人员

下载

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

type ServiceA struct {
    B *ServiceB // 显式依赖,非接口,非抽象
}

func (a *ServiceA) DoWork() { a.B.Notify("from A") }

type ServiceB struct { logs []string }

func (b *ServiceB) Notify(msg string) { b.logs = append(b.logs, msg) }

  • 没有隐藏的间接层,调用链清晰,IDE 跳转直接,pprof 分析无盲区
  • 只要 ServiceB 不暴露内部细节(如不导出 logs 字段),就满足封装要求
  • 如果未来真需要替换 ServiceB 实现,再提取接口也不迟——Go 主张“先具体,后抽象”

真正容易被忽略的是:中介者模式的初衷是降低多对多依赖的复杂度,但在 Go 里,**过度提前抽象带来的维护成本,常常远高于几个显式字段或回调函数带来的耦合**。先写清楚逻辑,再看是否真的需要“中介”。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

184

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

231

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

344

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

210

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

397

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

282

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

196

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

581

2025.06.17

java return合集
java return合集

本专题整合看java中return关键词的用途,语句的使用等等内容,阅读专题下面的文章了解更多详细内容。

0

2026.02.05

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 4.6万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号