【行为型之中介者模式】游戏开发实战——Unity复杂系统协调与通信架构的核心秘诀
文章目录
- 🕊️ 中介者模式(Mediator Pattern)深度解析
- 一、模式本质与核心价值
- 二、经典UML结构
- 三、Unity实战代码(成就系统协调)
- 1. 定义中介者接口与同事基类
- 2. 实现具体同事类
- 3. 实现具体中介者
- 4. 客户端使用
- 四、模式进阶技巧
- 1. 事件总线集成
- 2. 状态依赖管理
- 3. 优先级路由
- 五、游戏开发典型应用场景
- 六、性能优化策略
- 七、模式对比与选择
- 八、最佳实践原则
- 九、常见问题解决方案
🕊️ 中介者模式(Mediator Pattern)深度解析
——以Unity实现跨系统通信与复杂UI协调为核心案例
一、模式本质与核心价值
核心目标:
✅ 解耦对象间的直接依赖,通过中介者集中管理交互
✅ 简化网状通信为星型结构,提升系统可维护性
✅ 统一控制交互逻辑,便于扩展新通信规则
关键术语:
- Mediator(中介者接口):定义对象间通信的接口
- ConcreteMediator(具体中介者):实现协调逻辑
- Colleague(同事类):需要交互的对象,依赖中介者
数学表达:
设有N个对象,原始耦合度为O(N²),引入中介者M后降为O(N)
二、经典UML结构
三、Unity实战代码(成就系统协调)
1. 定义中介者接口与同事基类
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. 实现具体同事类
// 成就系统
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. 实现具体中介者
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. 客户端使用
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. 事件总线集成
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. 状态依赖管理
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. 优先级路由
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系统协调
public class UIMediator : IMediator {public void Notify(object sender, string eventType) {switch(eventType) {case "InventoryOpened":PauseGame();HideHUD();break;case "SettingsClosed":ResumeGame();ShowHUD();break;}} }
-
多人游戏同步
public class NetworkMediator : IMediator {public void Notify(object sender, string eventType, object data) {switch(eventType) {case "PlayerMove":BroadcastToAllClients(data);break;case "ChatMessage":ProcessChatMessage(data);break;}} }
-
任务系统协调
public class QuestMediator : IMediator {public void Notify(object sender, string eventType, Quest quest) {switch(eventType) {case "QuestStarted":UpdateQuestLog();PlayQuestStartSFX();break;case "QuestCompleted":GrantRewards();UpdateNPCdialogue();break;}} }
-
车辆控制系统
public class VehicleMediator : IMediator {public void Notify(object sender, string eventType) {if(sender is Engine && eventType == "Overheat") {ThrottleControl.ReducePower();CoolingSystem.ActivateEmergencyCooling();}} }
六、性能优化策略
策略 | 实现方式 | 适用场景 |
---|---|---|
事件过滤 | 提前终止不相关事件处理 | 高频事件系统 |
批处理 | 合并多个通知为单个操作 | 物理系统更新 |
缓存路由表 | 预生成事件处理映射 | 固定事件类型 |
异步处理 | 使用UniTask处理耗时操作 | 网络通信场景 |
七、模式对比与选择
维度 | 中介者模式 | 观察者模式 |
---|---|---|
关注点 | 集中协调 | 松散通知 |
耦合度 | 同事类依赖中介者 | 发布者/订阅者解耦 |
复杂度 | 较高(需维护中介者) | 较低 |
典型场景 | 复杂交互协调 | 简单事件通知 |
八、最佳实践原则
- 职责分离:避免中介者成为"上帝对象"
- 接口最小化:
public interface IGameMediator {void PlayerAction(PlayerActionType action);void UIEvent(UIEventType event); }
- 模块化中介者:
public 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);} }
- 异常隔离:
public void Notify(...) {try {// 处理逻辑} catch(Exception e) {Debug.LogError($"中介者处理异常:{e.Message}");} }
九、常见问题解决方案
Q1:如何防止中介者过度膨胀?
→ 实现分层中介者
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:如何处理循环通知?
→ 实现事件标记
public class Notification {public string Type;public bool IsProcessed;
}public void Notify(...) {if(notification.IsProcessed) return;notification.IsProcessed = true;// 处理逻辑
}
Q3:如何调试复杂事件流?
→ 实现事件追踪器
public class DebugMediator : IMediator {public void Notify(object sender, string eventType, object data) {Debug.Log($"[{Time.time}] 事件:{eventType} 发送者:{sender.GetType().Name}");// 传递给实际中介者...}
}
上一篇 【行为型之迭代器模式】游戏开发实战——Unity高效集合遍历与场景管理的架构精髓
下一篇 【行为型之备忘录模式】游戏开发实战——Unity存档系统与状态管理的终极解决方案