【行为型之中介者模式】游戏开发实战——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结构
«interface»
IMediator
+Notify(sender: object, event: string)
AchievementMediator
+Notify()
UIColleague
-mediator: IMediator
+OnUpdate()
AchievementSystem
-mediator: IMediator
+UnlockAchievement()

三、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);}}
}

五、游戏开发典型应用场景
  1. UI系统协调

    public class UIMediator : IMediator {public void Notify(object sender, string eventType) {switch(eventType) {case "InventoryOpened":PauseGame();HideHUD();break;case "SettingsClosed":ResumeGame();ShowHUD();break;}}
    }
    
  2. 多人游戏同步

    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;}}
    }
    
  3. 任务系统协调

    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;}}
    }
    
  4. 车辆控制系统

    public class VehicleMediator : IMediator {public void Notify(object sender, string eventType) {if(sender is Engine && eventType == "Overheat") {ThrottleControl.ReducePower();CoolingSystem.ActivateEmergencyCooling();}}
    }
    

六、性能优化策略
策略实现方式适用场景
事件过滤提前终止不相关事件处理高频事件系统
批处理合并多个通知为单个操作物理系统更新
缓存路由表预生成事件处理映射固定事件类型
异步处理使用UniTask处理耗时操作网络通信场景

七、模式对比与选择
维度中介者模式观察者模式
关注点集中协调松散通知
耦合度同事类依赖中介者发布者/订阅者解耦
复杂度较高(需维护中介者)较低
典型场景复杂交互协调简单事件通知

八、最佳实践原则
  1. 职责分离:避免中介者成为"上帝对象"
  2. 接口最小化
    public interface IGameMediator {void PlayerAction(PlayerActionType action);void UIEvent(UIEventType event);
    }
    
  3. 模块化中介者
    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);}
    }
    
  4. 异常隔离
    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存档系统与状态管理的终极解决方案

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/news/905663.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【网工第6版】第10章 网络规划和设计②

目录 ■ 网络分析与设计 ◆ 网络规划设计模型 ◆ 网络设计的约束因素 ◆ 技术评价 ■ 网络结构与功能 ◆ 局域网结构类型 ■ 网络冗余设计 ◆ 网络冗余设计-备用路径 ◆ 网络冗余设计-负载分担 ■ 广域网接入技术 ◆ 广域网接入技术 ◆ 接入和终结设备 ■ 网络分析…

PowerBI链接EXCEL实现自动化报表

PowerBI链接EXCEL实现自动化报表 曾经我将工作中一天的工作缩短至2个小时&#xff0c;其中最关键的一步就是使用PowerBI链接Excel做成一个自动化报表&#xff0c;PowerBI更新源数据&#xff0c;Excel更新报表并且保留报表格式。 以制作一个超市销售报表为例&#xff0c;简单叙…

C#.NET 或 VB.NET Windows 窗体中的 DataGridView – 技巧、窍门和常见问题

DataGridView 控件是一个 Windows 窗体控件&#xff0c;它允许您自定义和编辑表格数据。它提供了许多属性、方法和事件来自定义其外观和行为。在本文中&#xff0c;我们将讨论一些常见问题及其解决方案。这些问题来自各种来源&#xff0c;包括一些新闻组、MSDN 网站以及一些由我…

表记录的检索

1.select语句的语法格式 select 字段列表 from 表名 where 条件表达式 group by 分组字段 [having 条件表达式] order by 排序字段 [asc|desc];说明&#xff1a; from 子句用于指定检索的数据源 where子句用于指定记录的过滤条件 group by 子句用于对检索的数据进行分组 ha…

能源设备数据采集

在全球可持续发展目标与环境保护理念日益深入人心的时代背景下&#xff0c;有效管理和优化能源使用已成为企业实现绿色转型、提升竞争力的关键路径。能源设备数据采集系统&#xff0c;作为能源管理的核心技术支撑&#xff0c;通过对各类能源生产设备运行数据的全面收集、深度分…

【鸿蒙开发】性能优化

语言层面的优化 使用明确的数据类型&#xff0c;避免使用模糊的数据类型&#xff0c;例如ESObject。 使用AOT模式 AOT就是提前编译&#xff0c;将字节码提前编译成机器码&#xff0c;这样可以充分优化&#xff0c;从而加快执行速度。 未启用AOT时&#xff0c;一边运行一边进…

群晖NAS部署PlaylistDL音乐下载器结合cpolar搭建私有云音乐库

文章目录 前言1.关于PlaylistDL音乐下载器2.Docker部署3.PlaylistDL简单使用4.群晖安装Cpolar工具5.创建PlaylistDL音乐下载器的公网地址6.配置固定公网地址总结 前言 各位小伙伴们&#xff0c;你们是不是经常为了听几首歌而开通各种平台的VIP&#xff1f;或者为了下载无损音质…

REST架构风格介绍

一.REST&#xff08;表述性状态转移&#xff09; 1.定义 REST&#xff08;Representational State Transfer&#xff09;是由 Roy Fielding 在 2000 年提出的一种软件架构风格&#xff0c;用于设计网络应用的通信模式。它基于 HTTP 协议&#xff0c;强调通过统一的接口&#…

计算机视觉----基于锚点的车道线检测、从Line-CNN到CLRNet到CLRKDNet 本文所提算法Line-CNN 后续会更新以下全部算法

本文所提算法如下&#xff1a; 叙述按时间顺序 你也可以把本文当作快速阅读这几篇文献的一个途径 所有重要的部分我都已经标注并弄懂其原理 方便自己也是方便大家 Line-CNN&#xff1a;基于线提议单元的端到端交通线检测 摘要 交通线检测是一项基础且具有挑战性的任务。以往的…

一.android Studio开发系统应用——导入TvSettings源码

目标 最终效果如上,实现在AS中编辑源码后一键在真机中运行。达到和普通应用开发一样的调试和编码过程。这种方法可以大幅度提升开发速度,但是导入过程确实相对繁琐和消耗时间。适合需要精细或者频繁改动的系统app源码。 一、新建项目 包名:com.android.tv.settings 版本:…

20250515让飞凌的OK3588-C的核心板在Linux R4下适配以太网RTL8211F-CG为4线百兆时的接线图

20250515让飞凌的OK3588-C的核心板在Linux R4下适配以太网RTL8211F-CG为4线百兆时的接线图 2025/5/15 20:19 缘起&#xff1a;以前做的网线找不到了&#xff0c;那就再来一条吧。 引脚定义要从头来过&#xff1f;还好找到了一条。 开干&#xff01; 万用表一对/点&#xff0c;几…

【技术原理】Linux 文件时间属性详解:Access、Modify、Change 的区别与联系

在 Linux 系统中&#xff0c;每个文件都有三个核心时间属性&#xff1a;Access Time (atime)、Modify Time (mtime) 和 Change Time (ctime)。它们分别记录文件不同维度的变更信息&#xff0c;以下是具体区别与联系&#xff1a; 一、定义与触发条件 时间属性定义触发条件示例A…

乘法口诀练习神器

请你利用python语言开发一个“乘法口诀练习神器”&#xff0c;主要辅助小学生练习乘法口诀&#xff0c;主要功能如下&#xff1a; 1. 能够随机循环出10道题&#xff0c;可以是乘法或者是除法。如果是乘法&#xff0c;确保两个因数都是1-9之间的整数&#xff1b;如果是除法&…

[c语言日寄]数据结构:栈

【作者主页】siy2333 【专栏介绍】⌈c语言日寄⌋&#xff1a;这是一个专注于C语言刷题的专栏&#xff0c;精选题目&#xff0c;搭配详细题解、拓展算法。从基础语法到复杂算法&#xff0c;题目涉及的知识点全面覆盖&#xff0c;助力你系统提升。无论你是初学者&#xff0c;还是…

磁盘I/O瓶颈排查:面试通关“三部曲”心法

想象一下&#xff0c;你就是线上系统的“交通调度总指挥”&#xff0c;服务器的磁盘是所有数据进出的“核心枢纽港口”。当这个“港口”突然拥堵不堪&#xff0c;卡车&#xff08;数据请求&#xff09;排起长龙&#xff0c;进不去也出不来&#xff0c;整个系统的“物流”&#…

基于大模型预测胃穿孔预测与围手术期管理系统技术方案

目录 1. 系统架构模块2. 关键算法实现2.1 术前预测模型(Transformer多模态融合)2.2 术中实时分析(在线学习LSTM)3. 模块流程图(Mermaid)3.1 数据预处理系统3.2 术前预测系统3.3 术中实时分析系统4. 技术验证模块4.1 模型可解释性验证4.2 边缘计算部署架构1. 系统架构模块…

C++:类和对象4

一&#xff0c;日期类实现 学习建议&#xff1a; 对于计算机学习来说&#xff0c;调试十分重要&#xff0c;所以在日常学习中一定要加大代码练习&#xff0c;刷代码题和课后自己敲出课上代码例题&#xff0c;注意不要去对比正确代码或者网上找正确代码直接使用&#xff0c;一…

大数据架构选型分析

选择依据 1.业务需求与技术要求 用户需要根据自己的业务需求来选择架构&#xff0c;如果业务对于Hadoop、Spark、Strom等关键技术有强制性依赖&#xff0c;选择Lambda架构可能较为合适&#xff1b;如果处理数据偏好于流式计算&#xff0c;又依赖Flink计算引擎&#xff0c;那么…

Trae 插件 Builder 模式:从 0 到 1 开发天气查询小程序,解锁 AI 编程新体验

在软件开发领域&#xff0c;效率与创新始终是开发者追求的核心目标。Trae 插件&#xff08;原 MarsCode 编程助手&#xff09;Builder 模式的全面上线&#xff0c;无疑为开发者带来了全新的解决方案。它不仅同时支持 VS Code、JetBrains IDEs 等主流开发环境&#xff0c;还能让…

SSM项目集成redis、Linux服务器安装redis

在SSM&#xff08;Spring Spring MVC MyBatis&#xff09;项目中引入Redis主要分为以下步骤&#xff0c;确保配置正确并能在业务中灵活使用&#xff1a; 1. 添加Redis依赖​​ 在Maven的pom.xml中添加Spring Data Redis和Jedis&#xff08;或Lettuce&#xff09;依赖&#…