Golang学习笔记_48——中介者模式

news/2025/3/11 13:30:08/

Golang学习笔记_45——备忘录模式
Golang学习笔记_46——状态模式
Golang学习笔记_47——访问者模式


文章目录

    • 一、核心概念
      • 1. 定义
      • 2. 解决的问题
      • 3. 核心角色
      • 4. 类图
    • 二、特点分析
    • 三、适用场景
      • 1. 航空管制系统
      • 2. 分布式交易系统
      • 3. GUI组件交互
    • 四、Go语言实现示例
      • 完整实现代码
      • 执行结果
    • 五、高级应用
      • 1. 智能路由中介
      • 2. 事务协调器
    • 六、与其他模式对比
    • 七、实现建议
    • 八、典型应用


一、核心概念

1. 定义

中介者模式是一种行为型设计模式,通过引入中介对象来封装一组对象间的交互,实现对象间解耦。其核心特点包括:

  • 交互中心化:所有对象通信通过中介者进行
  • 解耦网络:消除对象间的直接依赖关系
  • 动态协调:可随时调整交互规则而不影响对象

2. 解决的问题

复杂网状依赖:对象间直接引用形成复杂网络
修改扩散风险:单个对象变更影响多个关联对象
复用困难:因高度耦合导致组件难以独立复用

3. 核心角色

角色作用
Mediator定义对象间通信接口
ConcreteMediator实现具体协调逻辑,维护同事对象引用
Colleague定义同事对象接口,持有中介者引用
ConcreteColleague具体业务对象,通过中介者与其他对象交互

4. 类图

<a class=中介者模式类图" />

@startuml
interface Mediator {+ notify(sender: Colleague, event: string)
}class ControlTower {- airplanes: List<Airplane>+ notify(sender: Airplane, event: string)
}interface Colleague {+ setMediator(mediator: Mediator)
}class Airplane {- mediator: Mediator+ requestLanding()+ receive(message: string)
}Mediator <|-- ControlTower
Colleague <|-- Airplane
ControlTower --> Airplane : managesnote right of ControlTower::notify根据事件类型协调飞机起降例如处理着陆请求或跑道释放通知
end note
@enduml

二、特点分析

优点

  1. 简化依赖:将N:N关系转为1:N关系
  2. 集中控制:交互规则统一维护于中介者
  3. 职责清晰:各对象专注核心职责

缺点

  1. 复杂度转移:中介者可能成为复杂单体
  2. 性能瓶颈:高频通信场景存在吞吐限制
  3. 过度设计:简单场景增加不必要抽象

三、适用场景

1. 航空管制系统

type AirTrafficControl interface {RequestLanding(planeID string)NotifyTakeoff(planeID string)
}type Boeing747 struct {controlTower AirTrafficControl
}func (b *Boeing747) LandingRequest() {b.controlTower.RequestLanding("BOEING-747")
}

2. 分布式交易系统

type TradeMediator interface {ExecuteOrder(order Order, traderID string)
}type StockExchange struct {participants map[string]Trader
}func (s *StockExchange) ExecuteOrder(o Order, src string) {for id, trader := range s.participants {if id != src {trader.ReceiveOrder(o)}}
}

3. GUI组件交互

type UIComponent interface {OnClick(mediator UIMediator)
}type LoginDialog struct {mediator UIMediator
}func (l *LoginDialog) Submit() {l.mediator.Notify(l, "submit")
}

四、Go语言实现示例

示例类图

完整实现代码

package mediator_demoimport ("fmt""sync"
)// Mediator Interface
type ChatMediator interface {Register(user User)Broadcast(sender User, message string)
}// Concrete Mediator
type chatRoom struct {users map[string]Userlock  sync.RWMutex
}func NewChatRoom() ChatMediator {return &chatRoom{users: make(map[string]User),}
}func (c *chatRoom) Register(user User) {c.lock.Lock()defer c.lock.Unlock()c.users[user.GetID()] = user
}func (c *chatRoom) Broadcast(sender User, msg string) {c.lock.RLock()defer c.lock.RUnlock()for id, user := range c.users {if id != sender.GetID() {user.Receive(sender.GetName(), msg)}}
}// Colleague Interface
type User interface {GetID() stringGetName() stringSend(message string)Receive(sender string, message string)
}// Concrete Colleague
type chatUser struct {id       stringname     stringmediator ChatMediator
}func NewUser(id, name string, med ChatMediator) User {u := &chatUser{id:       id,name:     name,mediator: med,}med.Register(u)return u
}func (c *chatUser) GetID() string  { return c.id }
func (c *chatUser) GetName() string { return c.name }func (c *chatUser) Send(msg string) {fmt.Printf("[%s] 发送消息: %s\n", c.name, msg)c.mediator.Broadcast(c, msg)
}func (c *chatUser) Receive(sender, msg string) {fmt.Printf("[%s] 收到来自 %s 的消息: %s\n", c.name, sender, msg)
}// 客户端使用示例
func ExampleUsage() {room := NewChatRoom()user1 := NewUser("001", "Alice", room)user2 := NewUser("002", "Bob", room)user3 := NewUser("003", "Charlie", room)user1.Send("大家好!")user2.Send("欢迎新人!")user3.Send("需要帮助吗?")
}

执行结果

=== RUN   TestExampleUsage
[Alice] 发送消息: 大家好!
[Bob] 收到来自 Alice 的消息: 大家好!
[Charlie] 收到来自 Alice 的消息: 大家好!
[Bob] 发送消息: 欢迎新人!
[Alice] 收到来自 Bob 的消息: 欢迎新人!
[Charlie] 收到来自 Bob 的消息: 欢迎新人!
[Charlie] 发送消息: 需要帮助吗?
[Alice] 收到来自 Charlie 的消息: 需要帮助吗?
[Bob] 收到来自 Charlie 的消息: 需要帮助吗?
--- PASS: TestExampleUsage (0.00s)
PASS

五、高级应用

1. 智能路由中介

type SmartRouter struct {nodes      map[string]NodetrafficMgr *TrafficAnalyzer
}func (s *SmartRouter) Route(message Message) {if s.trafficMgr.IsCongested(message.Destination) {s.RedirectToBackup(message)} else {s.SendDirect(message)}
}

2. 事务协调器

type TransactionCoordinator struct {services []MicroservicesagaLog  *SagaLogger
}func (t *TransactionCoordinator) BeginSaga() {for _, svc := range t.services {if err := svc.Prepare(); err != nil {t.CompensateAll()break}}
}

六、与其他模式对比

模式核心区别典型应用场景
观察者模式广播通知 vs 定向协调事件订阅系统
代理模式控制访问 vs 协调交互延迟加载对象
门面模式简化接口 vs 协调交互复杂子系统封装

七、实现建议

  1. 接口分层设计
type AdvancedMediator interface {Register(Colleague)Unregister(string)QueryColleagues(filter func(Colleague) bool) []Colleague
}
  1. 并发安全处理
type SafeMediator struct {colleagues sync.Map
}func (s *SafeMediator) Register(c Colleague) {s.colleagues.Store(c.ID(), c)
}
  1. 消息协议优化
type Message struct {Header map[string]stringBody   []byteMetadata ProtocolMetadata
}
  1. 性能监控扩展
type InstrumentedMediator struct {mediator    Mediatormetrics     *PrometheusCollector
}func (i *InstrumentedMediator) Broadcast(msg Message) {start := time.Now()i.mediator.Broadcast(msg)i.metrics.ObserveLatency(time.Since(start))
}

八、典型应用

  1. 微服务编排:服务间调用协调
  2. 物联网中枢:设备联动控制中心
  3. 多人游戏同步:玩家动作协调引擎
  4. 工作流引擎:任务节点调度中枢

在Go语言中实现建议:

  • 使用context.Context传递协调上下文
  • 结合channel实现事件总线机制
  • 采用接口组合实现策略可插拔
  • 利用sync.Pool优化高频消息对象

http://www.ppmy.cn/news/1578355.html

相关文章

界面组件DevExpress WPF中文教程:Grid - 如何创建栏(Bands)?

DevExpress WPF拥有120个控件和库&#xff0c;将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序&#xff0c;这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 无论是Office办公软件…

DINOv2:无监督学习强大的视觉特征

Paper Title: DINOv2: Learning Robust Visual Features without Supervision 论文发布于CVPR2023 DINOv2是一种无监督学习的计算机视觉模型,该模型在处理多种视觉任务时,不需要进行微调便能提供优异的性能。 上图展示了 PCA(主成分分析)方法在图像补丁上的应用。具体来说…

python中如何把dataframe转换为列表及其性能比较

在Python中&#xff0c;将DataFrame转换为列表常用的方法有以下几种&#xff1a; ### 1. 使用values属性 先通过values属性将DataFrame转换为NumPy数组&#xff0c;然后再调用tolist()方法将数组转换为列表。这是一种简单直接的方式&#xff0c;适用于快速将整个DataFrame转换…

三维仿射变换矩阵

三维仿射变换矩阵 平移变换缩放变换旋转变换绕x、y、z单个轴旋转的变换绕任意轴旋转 三维仿射变换矩阵有 3 4 、 4 4 3\times4、4\times4 34、44两种写法&#xff0c;都是施加到三维点的齐次式上&#xff0c; 4 4 4\times4 44的仿射变换矩阵是在 3 4 3\times4 34的矩阵后追…

Node.js和Vue CLI 安装指南(Windows 系统)

Node.js 与 Vue CLI 安装指南&#xff08;Windows 系统&#xff09; 一、Node.js 安装步骤 1. 安装包获取 官网下载&#xff1a;Node.js 官网推荐选择 LTS 版本&#xff08;长期支持版&#xff09;双击运行安装包&#xff1a; 2. 安装向导配置 点击 "Next" 进入…

本周行情——20250308

本周A股行情总结及主线阶段分析 &#xff08;2025年3月3日-3月7日&#xff09; 一、整体行情回顾 市场情绪&#xff1a; 前半周&#xff08;3月3日-5日&#xff09;&#xff1a;市场情绪持续回暖&#xff0c;涨停家数从66家增至115家&#xff0c;主线板块&#xff08;机器人、…

Docker入门篇1:搜索镜像、拉取镜像、查看本地镜像列表、删除本地镜像

大家好我是木木&#xff0c;在当今快速发展的云计算与云原生时代&#xff0c;容器化技术蓬勃兴起&#xff0c;Docker 作为实现容器化的主流工具之一&#xff0c;为开发者和运维人员带来了极大的便捷 。下面我们一起开始入门第一篇&#xff1a;搜索镜像、拉取镜像、查看本地镜像…

NO.29十六届蓝桥杯备战|string九道练习|reverse|翻转|回文(C++)

P5015 [NOIP 2018 普及组] 标题统计 - 洛谷 #include <bits/stdc.h> using namespace std;int main() {ios::sync_with_stdio(false);cin.tie(nullptr);string s;getline(cin, s);int sz s.size();int cnt 0;for (int i 0; i < sz; i){if (isspace(s[i]))continue…