中介者模式 (Mediator Pattern)

核心思想: 定义一个对象, 封装一系列对象的交互方式. 它使对象之间无需显式引用, 从而降低耦合度, 并可以独立地改变它们之间的交互.
 
你可以把中介模式想象成一个”中央调度中心”或者”空气 traffic controller”. 在一个复杂的系统中, 多个对象(比如飞机)之间如果直接通信, 会形成错综复杂的关系网, 难以维护和扩展. 中介者模式的核心思想就是: 定义一个”中介者”对象, 让所有相关对象都通过它来通信, 而不是直接相互引用. 这样一来, 对象之间的耦合度就降低了, 系统也变得更加灵活和易于管理.
 

举个具体场景: 游戏中的UI面板交互

假设你正在开发一个角色扮演游戏(RPG), 有以下几个UI面板和系统:
  1. 角色面板(CharacterPanel): 显示角色的生命值\魔法值\装备等.
  1. 背包面板(InventoryPanel): 显示玩家拥有的物品, 点击物品可以装备或使用.
  1. 技能面板(SkillPanel): 显示玩家的技能, 点击技能可以释放
  1. 战斗系统(CombatSystem): 处理战斗逻辑, 当角色受到伤害时, 无需通知角色面板更新生命值
 
如果不使用中介者模式, 这些面板和系统之间会直接调用彼此的方法, 比如:
  • InventoryPanel 中的”装备”按钮被点击时, 需要直接调用 CharacterPanel.UpdateEquipment() 方法来更新角色外观
  • CombatSystem 计算出角色受到伤害后, 直接调用 CharacterPanel.UpdateHealth() 方法来更新血条
  • SkillPanel 中的技能被点击时, 需要直接调用 CombatSystem.CastSkill() 方法
 
这样会导致”紧耦合:
  • InventoryPane 必须知道 CharacterPanel的存在, 并且知道它有一个 UpdateEquipment 方法
  • 如果以后想把 CharacterPanel 重命名或者修改 UpdateHealth 方法的参数, 就必须找到所有调用它的地方并一一修改, 非常容易出错
 

 

中介者模式如何解决这个问题?

我们引入一个”UI中介者”(UIMediator)
 
  1. 所有UI面板和系统都只与 UImediator 通信
  1. 当一个面板发生变化时(比如背包里的物品被点击), 它只需要”通知UIMediator 发生了什么事.
  1. UIMediator 知道所有其他面板和系统, 它会根据受到的通知, 去”协调”其他相关的面板或系统做出反应
 

 

代码实步骤

  1. 定义抽象中介接口(Mediator)
这个接口定义了中介者需要处理的事件类型
 
  1. 实现具体中介者(Concrete Mediator)
这是中介者模式的核心, 它持有所有需要交互的对象的引用, 并实现了协调逻辑
 
  1. 实现同事类(Colleague)
这些是系统中的各个对象, 它们只知道中介者, 并通过中介者进行通信
 

在Unity编译器中如何配置

  1. 创建一个空 GameObject,命名为 GameManager
  1. 给 GameManager 添加 UIMediator 脚本。
  1. 在场景中创建代表各个面板的 UI GameObject(如 CharacterPanelInventoryPanel 等),并给它们添加相应的脚本。
  1. 在 GameManager 的 UIMediator 组件的 Inspector 面板中,将场景中的各个面板和系统拖到对应的字段中。
  1. 编写测试代码来模拟用户交互,例如:
 
 

中介者模式的核心优势

  1. 降低耦合度: 同时类之间不再直接引用, 所有通信都通过中介者进行, 使得系统更加松耦合.
  1. 集中控制交互: 将复杂的交互逻辑集中在中介者中, 是的各个同事类的职责更加单一和清晰
  1. 易于扩展和维护
      • 新增同事类:只需要让它与中介者通信即可,无需修改其他同事类。
      • 修改交互逻辑:只需要修改中介者中的代码,而不用在多个同事类之间来回修改。
  1. 简化对象的协议: 对象不再需要知道其他对象的协议, 只需要知道中介者的协议即可.
 

模式的适用场景

  • 当系统中对象之间存在复杂的引用关系, 导致依赖关系混乱且难以复用改对象时.
  • 当向通过一个中间类封装多个类中的行为, 而又不想生成太多子类时.
  • 当需要创建一个运行时系统, 由多个对象动态交互时.
 

一个形象的比喻

想象一下一个大公司的各个部门(开发部\市场部\财务部). 如果每个部门都直接和其他部门沟通, 会非常混乱. 这时就需要一个”项目经理”(中介者).
  • 开发部完成了一个功能, 它只需要告诉项目经理
  • 项目经理再根据这个信息, 去通知市场部可以开始宣传了, 同时通知财务部这个功能的开发成本
  • 各个部门之间不需要知道对方在做什么, 只需要和项目经理打交道.
 
这个项目经理就是中介模式的体现
 
总结: 终结者模式通过引入一个中心协调者, 将多对多的复杂关系简化为一对多的关系, 时解决对象间紧耦合问题的有力工具