go-patterns责任链与中介者模式实战:解耦请求处理与组件通信的2个技巧
go-patterns责任链与中介者模式实战:解耦请求处理与组件通信的2个技巧
【免费下载链接】go-patternsDesign patterns for the Go programming language项目地址: https://gitcode.com/gh_mirrors/gopat/go-patterns
Go 设计模式库 go-patterns 提供了经典设计模式最易读的 Go 语言实现。本文挑选其中两个行为型模式——责任链模式与中介者模式,带你掌握 2 个实战技巧:用处理者责任链解耦请求处理,用中介者对象解耦组件之间的通信。无论是做中间件开发还是多模块协作系统,这 2 个技巧都能让你的 Go 代码告别面条式耦合。
项目速览:Go 设计模式示例在哪里
go-patterns 将经典 Go 设计模式整理为三大包,每个文件都是一个可直接阅读、可运行的完整示例:
| 包 | 定位 | 代表模式 |
|---|---|---|
behavioral/ | 对象通信模式 | 责任链、中介者、观察者、策略 |
creational/ | 对象创建模式 | 单例、建造者、工厂方法 |
structural/ | 对象组合模式 | 适配器、装饰器、代理 |
本文的两个模式都在行为型包中:
- 责任链:
behavioral/chain_of_responsibility.go - 中介者:
behavioral/mediator.go
每个模式都附带测试文件(如behavioral/chain_of_responsibility_test.go),边读边验证,上手零门槛。
技巧一:用责任链模式解耦请求处理
责任链模式解决什么问题
想象一个在线客服系统:用户请求可能由人工坐席、自动应答或升级流程处理。如果发送方代码里写满"如果……就转给谁"的判断,每新增一个处理者都要改一遍原代码——这是典型的紧耦合。
责任链模式的核心思路:把请求交给链上的多个对象,让它们依次获得处理机会,请求沿链传递,直到被某个对象处理为止。发送方只负责把请求扔进链头,完全不需要知道最终是谁处理的。
处理者链是怎么串起来的
示例中定义了一个统一的Handler接口,每个处理者内部持有指向下一个处理者的next指针,处理逻辑极其简单:
func (h *handler) Handle(handleID int) string { if h.handleID == handleID { return h.name + " handled " + strconv.Itoa(handleID) } return h.next.Handle(handleID) }三行逻辑一句话概括:是我的我处理,不是的传给下一个。完整实现见behavioral/chain_of_responsibility.go(Handle方法,L23-L29)。
3 行代码搭一条链
用NewHandler依次把处理者接起来,责任链就搭好了:
barry := NewHandler("Barry", nil, 1) paul := NewHandler("Paul", barry, 2) paul.Handle(1) // 输出: Barry handled 1测试behavioral/chain_of_responsibility_test.go中可以看到:Paul 收到请求1匹配不到,就自动交给链上的 Barry 处理——请求由谁接手,对调用方完全透明。✨
技巧二:用中介者模式解耦组件通信
组件直接通信为什么难维护
N 个人组成的聊天群里,若每个人都要直接给其他所有人发消息,通信路径多达 N×(N-1) 条,增减一个成员都要改动所有相关方。多模块系统同理:对象互相直接引用,依赖关系会织成一张乱网。
中介者模式的角色很直白:设立一个"调解人",所有参与者只跟中介者说话,彼此互不认识。通信规则集中在中介者对象里,参与者之间彻底松耦合。
中介者实战:Bill 与 Ted 的对话
项目示例借用了电影里的经典对白:Ted 喊一声 "Bill?",Bill 回应。关键在于 Ted 和 Bill 从不直接调用对方,各自只持有一个Mediator接口引用:
type Mediator interface { Communicate(who string) }ConcreateMediator集中了路由规则——谁说话、谁回应(见behavioral/mediator.go,L66-L73):
func (m *ConcreateMediator) Communicate(who string) { if who == "Ted" { m.Bill.Respond() } else if who == "Bill" { m.Ted.Respond() } }NewMediator()构造时还会把中介者统一注入各参与者。之后 Ted 调用Talk(),由中介者负责找到 Bill 让他回应。完整的交互输出可以在测试behavioral/mediator_test.go中验证。💬
责任链 vs 中介者:2 个模式怎么选
| 对比点 | 责任链 | 中介者 |
|---|---|---|
| 核心目的 | 解耦请求发送方与接收方 | 解耦多个组件间的相互通信 |
| 交互形态 | 请求沿链单向传递 | 所有人对"中央调解人" |
| 适用场景 | 中间件管道、审批流、异常升级 | 群聊、多模块协作、UI 组件联动 |
| go-patterns 示例 | behavioral/chain_of_responsibility.go | behavioral/mediator.go |
一句话记忆:线性传递选责任链,多方对话选中介者。⚡
一键克隆并运行测试
想更深入阅读源码,可以获取 go-patterns 项目并运行行为型包测试:
git clone https://gitcode.com/gh_mirrors/gopat/go-patterns cd go-patterns go test ./behavioral/所有测试用例基于testify断言编写,运行一次即可完成一次自检。
小结
- 责任链:统一
Handler接口 +next指针,请求沿链传递直到被处理,发送方与接收方彻底解耦 - 中介者:参与者只持有
Mediator接口引用,通信规则集中在中介者对象中 - go-patterns 的
behavioral/包为两个模式都提供了最小化、可运行的示例,配合对应测试文件即可快速上手
2 个技巧就讲完了,下次写 Go 请求处理或多组件协作时,直接从 go-patterns 中取对应模式做模板即可。
【免费下载链接】go-patternsDesign patterns for the Go programming language项目地址: https://gitcode.com/gh_mirrors/gopat/go-patterns
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
