go中中介者模式应采用接口定义契约、结构体组合实现,同事对象显式声明具体类型并注入中介者,所有交互统一经中介者方法协调,杜绝直连调用。

Go 里没有继承,中介者模式怎么写才不别扭
直接说结论:用接口 + 结构体组合,别硬套经典 UML 类图。Go 的中介者不是靠“抽象中介者类”和“具体中介者类”两层继承,而是靠 Mediator 接口定义协调契约,再让具体协调逻辑落在某个结构体里——这个结构体同时持有对各同事对象的引用,并负责转发/转换它们之间的交互。
常见错误是试图用空接口 interface{} 或泛型过度抽象同事类型,结果导致类型安全丢失、调用时反复断言。其实多数场景下,同事角色是明确的(比如 User、ChatRoom、NotificationService),直接在中介者结构体里用具体类型字段更清晰、更易调试。
- 中介者结构体字段应显式声明所协调的同事类型,例如
users map[string]*User、room *ChatRoom - 同事对象不持有中介者指针,而是通过构造函数或方法注入,避免循环引用
- 所有通信入口统一走中介者的某个方法(如
Send(message string, from string, to string)),而不是让同事互相调用
同事对象怎么设计才不会偷偷绕过中介者
关键在“切断直连”。如果 User 里还存着 *ChatRoom 或能直接调 notification.Send(),那中介者就形同虚设。
典型错误现象:User.SendMessage() 内部直接调用了 chatRoom.Broadcast(),完全没经过中介者。这说明设计时没把“职责隔离”当真。
- 同事结构体只保留自身状态和基础行为(如
User.Name、User.ID、User.SetStatus()) - 所有跨对象操作必须封装成“事件”或“请求”,由中介者统一接收(如
mediator.HandleUserJoin(user.ID, roomID)) - 同事对象的方法签名里不要出现其他同事类型的参数;若需传递,用 ID、字符串、DTO 结构体等中间载体
为什么不用 channel 实现中介者?它看起来更 Go 风格
channel 确实 Go 味十足,但用于中介者容易滑向“消息总线”或“事件总线”,反而模糊了“协调逻辑归属”的边界。真正的中介者要能做判断、改写、拦截、合并——这些不适合塞进无缓冲 channel 或 select case 里硬编码。
Go语言(Golang)1.26.0版本提供 Go 官方 Windows amd64 MSI 安装包下载入口,版本号 1.26.0,可用于旧项目维护、兼容性测试和指定版本开发环境配置。
常见误用:开一个全局 chan Message,所有对象往里塞 Message{From: "user1", To: "room2", Payload: ...},然后起个 goroutine 盲转发。结果是逻辑散落、无法拦截敏感操作、难以测试路由规则。
- channel 适合解耦生产者/消费者节奏,不适合承载业务协调逻辑
- 真正需要条件判断(如“只有管理员才能踢人”)、状态检查(如“房间已满则拒绝加入”)、副作用处理(如“用户退出时自动发离线通知”)的地方,必须落在中介者结构体的方法里
- 如果真要用 channel,建议仅作为中介者内部的输入队列(
mediator.inputCh chan *Event),主协调逻辑仍在方法中
嵌入式中介者(Embedded Mediator)在组合场景下的坑
当多个模块各自有小范围协调需求(比如一个订单流程里,支付、库存、物流要轻量协同),有人会把 Mediator 嵌入到某个服务结构体里。这看似方便,实则危险:嵌入后容易变成“伪中介者”,实际仍是 A 调 B、B 调 C 的链式调用,只是多了一层转发壳。
典型错误现象:OrderService 嵌入了 mediator 字段,但它的 CreateOrder() 方法里仍直接调 payment.Charge() 和 inventory.Lock(),只把日志或回调扔给 mediator.Notify()。
- 嵌入中介者 ≠ 使用中介者;必须确保所有跨组件调用路径都收束到中介者方法内
- 如果只是想复用协调逻辑,优先考虑独立的中介者实例 + 显式传参,而非结构体嵌入
- 测试时重点验证:去掉中介者实例后,同事对象是否真的无法完成协作?如果还能跑通,说明中介者没起作用
中介者最难的不是写法,是识别出哪些交互“本该被拦下来”。一旦发现两个对象之间存在条件分支、状态依赖、权限判断或副作用联动,那里就是中介者该插手的位置——不是为了炫技,是为了让下次改“踢人规则”时,只改一个地方。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










