文章目录
-
-
- [🕊️ 中介者模式(Mediator Pattern)深度解析](#🕊️ 中介者模式(Mediator Pattern)深度解析)
-
- 一、模式本质与核心价值
- 二、经典UML结构
- 三、Unity实战代码(成就系统协调)
-
- [1. 定义中介者接口与同事基类](#1. 定义中介者接口与同事基类)
- [2. 实现具体同事类](#2. 实现具体同事类)
- [3. 实现具体中介者](#3. 实现具体中介者)
- [4. 客户端使用](#4. 客户端使用)
- 四、模式进阶技巧
-
- [1. 事件总线集成](#1. 事件总线集成)
- [2. 状态依赖管理](#2. 状态依赖管理)
- [3. 优先级路由](#3. 优先级路由)
- 五、游戏开发典型应用场景
- 六、性能优化策略
- 七、模式对比与选择
- 八、最佳实践原则
- 九、常见问题解决方案
-
🕊️ 中介者模式(Mediator Pattern)深度解析
------以Unity实现跨系统通信 与复杂UI协调为核心案例
一、模式本质与核心价值
核心目标 :
✅ 解耦对象间的直接依赖 ,通过中介者集中管理交互
✅ 简化网状通信 为星型结构,提升系统可维护性
✅ 统一控制交互逻辑,便于扩展新通信规则
关键术语:
- Mediator(中介者接口):定义对象间通信的接口
- ConcreteMediator(具体中介者):实现协调逻辑
- Colleague(同事类):需要交互的对象,依赖中介者
数学表达 :
设有N个对象,原始耦合度为O(N²),引入中介者M后降为O(N)
二、经典UML结构
<<interface>> IMediator +Notify(sender: object, event: string) AchievementMediator +Notify() UIColleague -mediator: IMediator +OnUpdate() AchievementSystem -mediator: IMediator +UnlockAchievement()
三、Unity实战代码(成就系统协调)
1. 定义中介者接口与同事基类
csharp
public interface IMediator {
void Notify(object sender, string eventType, object data = null);
}
public abstract class Colleague : MonoBehaviour {
[SerializeField] protected IMediator mediator;
public void SetMediator(IMediator mediator) {
this.mediator = mediator;
}
}
2. 实现具体同事类
csharp
// 成就系统
public class AchievementSystem : Colleague {
public void Unlock(string achievementID) {
Debug.Log($"解锁成就:{achievementID}");
mediator?.Notify(this, "AchievementUnlocked", achievementID);
}
}
// UI弹窗系统
public class UIPopup : Colleague {
public void ShowAchievementPopup(string title) {
Debug.Log($"显示成就弹窗:{title}");
}
}
// 音效系统
public class SFXSystem : Colleague {
public void Play(string clipName) {
Debug.Log($"播放音效:{clipName}");
}
}
3. 实现具体中介者
csharp
public class AchievementMediator : IMediator {
private AchievementSystem _achievement;
private UIPopup _popup;
private SFXSystem _sfx;
public AchievementMediator(AchievementSystem a, UIPopup u, SFXSystem s) {
_achievement = a;
_popup = u;
_sfx = s;
_achievement.SetMediator(this);
_popup.SetMediator(this);
_sfx.SetMediator(this);
}
public void Notify(object sender, string eventType, object data) {
switch(eventType) {
case "AchievementUnlocked":
HandleAchievementUnlocked(data.ToString());
break;
case "PopupClosed":
HandlePopupClosed();
break;
}
}
private void HandleAchievementUnlocked(string id) {
_popup.ShowAchievementPopup(GetAchievementTitle(id));
_sfx.Play("AchievementUnlocked");
SaveSystem.SaveAchievement(id);
}
private void HandlePopupClosed() {
_sfx.Play("ButtonClick");
}
}
4. 客户端使用
csharp
public class GameManager : MonoBehaviour {
[SerializeField] private AchievementSystem achievement;
[SerializeField] private UIPopup popup;
[SerializeField] private SFXSystem sfx;
private IMediator _mediator;
void Start() {
_mediator = new AchievementMediator(achievement, popup, sfx);
}
void Update() {
if(Input.GetKeyDown(KeyCode.A)) {
achievement.Unlock("KILL_100_ENEMIES");
}
}
}
四、模式进阶技巧
1. 事件总线集成
csharp
public class EventMediator : IMediator {
private Dictionary<Type, List<Action<object>>> _handlers = new();
public void Subscribe<T>(Action<T> handler) {
var type = typeof(T);
if(!_handlers.ContainsKey(type)) {
_handlers[type] = new List<Action<object>>();
}
_handlers[type].Add(obj => handler((T)obj));
}
public void Notify(object sender, string eventType, object data) {
if(_handlers.TryGetValue(data.GetType(), out var handlers)) {
foreach(var h in handlers) h(data);
}
}
}
2. 状态依赖管理
csharp
public class StateDependentMediator : IMediator {
private Dictionary<GameState, Action<object>> _stateHandlers = new();
public void RegisterStateHandler(GameState state, Action<object> handler) {
_stateHandlers[state] = handler;
}
public void Notify(object sender, string eventType, object data) {
if(_stateHandlers.TryGetValue(GameManager.CurrentState, out var handler)) {
handler(data);
}
}
}
3. 优先级路由
csharp
public class PriorityMediator : IMediator {
private List<(int priority, Action<object>)> _handlers = new();
public void AddHandler(int priority, Action<object> handler) {
_handlers.Add((priority, handler));
_handlers.Sort((a,b) => b.priority.CompareTo(a.priority));
}
public void Notify(object sender, string eventType, object data) {
foreach(var h in _handlers) {
h.handler(data);
}
}
}
五、游戏开发典型应用场景
-
UI系统协调
csharppublic class UIMediator : IMediator { public void Notify(object sender, string eventType) { switch(eventType) { case "InventoryOpened": PauseGame(); HideHUD(); break; case "SettingsClosed": ResumeGame(); ShowHUD(); break; } } }
-
多人游戏同步
csharppublic class NetworkMediator : IMediator { public void Notify(object sender, string eventType, object data) { switch(eventType) { case "PlayerMove": BroadcastToAllClients(data); break; case "ChatMessage": ProcessChatMessage(data); break; } } }
-
任务系统协调
csharppublic class QuestMediator : IMediator { public void Notify(object sender, string eventType, Quest quest) { switch(eventType) { case "QuestStarted": UpdateQuestLog(); PlayQuestStartSFX(); break; case "QuestCompleted": GrantRewards(); UpdateNPCdialogue(); break; } } }
-
车辆控制系统
csharppublic class VehicleMediator : IMediator { public void Notify(object sender, string eventType) { if(sender is Engine && eventType == "Overheat") { ThrottleControl.ReducePower(); CoolingSystem.ActivateEmergencyCooling(); } } }
六、性能优化策略
策略 | 实现方式 | 适用场景 |
---|---|---|
事件过滤 | 提前终止不相关事件处理 | 高频事件系统 |
批处理 | 合并多个通知为单个操作 | 物理系统更新 |
缓存路由表 | 预生成事件处理映射 | 固定事件类型 |
异步处理 | 使用UniTask处理耗时操作 | 网络通信场景 |
七、模式对比与选择
维度 | 中介者模式 | 观察者模式 |
---|---|---|
关注点 | 集中协调 | 松散通知 |
耦合度 | 同事类依赖中介者 | 发布者/订阅者解耦 |
复杂度 | 较高(需维护中介者) | 较低 |
典型场景 | 复杂交互协调 | 简单事件通知 |
八、最佳实践原则
-
职责分离:避免中介者成为"上帝对象"
-
接口最小化 :
csharppublic interface IGameMediator { void PlayerAction(PlayerActionType action); void UIEvent(UIEventType event); }
-
模块化中介者 :
csharppublic class CompositeMediator : IMediator { private List<IMediator> _subMediators = new(); public void AddMediator(IMediator m) => _subMediators.Add(m); public void Notify(object sender, string eventType, object data) { foreach(var m in _subMediators) m.Notify(sender, eventType, data); } }
-
异常隔离 :
csharppublic void Notify(...) { try { // 处理逻辑 } catch(Exception e) { Debug.LogError($"中介者处理异常:{e.Message}"); } }
九、常见问题解决方案
Q1:如何防止中介者过度膨胀?
→ 实现分层中介者
csharp
public class HierarchyMediator : IMediator {
private Dictionary<SystemType, IMediator> _subMediators = new();
public void Notify(...) {
if(_subMediators.TryGetValue(GetSystemType(sender), out var mediator)) {
mediator.Notify(sender, eventType, data);
}
}
}
Q2:如何处理循环通知?
→ 实现事件标记
csharp
public class Notification {
public string Type;
public bool IsProcessed;
}
public void Notify(...) {
if(notification.IsProcessed) return;
notification.IsProcessed = true;
// 处理逻辑
}
Q3:如何调试复杂事件流?
→ 实现事件追踪器
csharp
public class DebugMediator : IMediator {
public void Notify(object sender, string eventType, object data) {
Debug.Log($"[{Time.time}] 事件:{eventType} 发送者:{sender.GetType().Name}");
// 传递给实际中介者...
}
}
上一篇 【行为型之迭代器模式】游戏开发实战------Unity高效集合遍历与场景管理的架构精髓
下一篇 【行为型之备忘录模式】游戏开发实战------Unity存档系统与状态管理的终极解决方案