UE开发中的设计模式(二) —— 中介者模式

news2024/9/21 16:35:37

上一篇文章介绍了观察者模式如何降低观察者和目标之间的耦合,并通过一个实例具体实现了观察者模式,本篇文章从上篇文章的实例继续,介绍中介者模式是如何带来对象间进一步的松耦合。

文章目录

  • 问题提出
  • 概述
  • 问题解决
  • 总结
    • 优点
    • 缺点
    • 模式应用
  • 参考资料

问题提出

上篇文章用一个实例介绍了观察者模式,具体就是场景中有多个敌人,有一个UI文本显示场景中的剩余敌人数,还有一个大门,当敌人被消灭完后打开。那么当敌人死亡时,就需要发布通知,而UI文本和大门就会收到消息执行相关流程。

我们通过观察者模式实现了敌人并不需要知道订阅者的信息,只需要简单地发布通知即可,具体对订阅者进行通知是通过抽象的目标。下面分析下还存在什么问题,看下面大门的蓝图,可以看到大门还是需要获取敌人对象数组,以设置敌人数量和绑定接收通知的事件。同样UI中也需要相同的操作,这样带来的问题一个是,订阅者依赖发布者的信息造成耦合,另一个是每有一个新的订阅者都需要先获取到所有敌人,但其实想一想这个信息是共享的,要是能只获取到一次就完美了。

这时引出中介者模式(Mediator Pattern)解决这些问题。


概述

中介者模式也是一种行为型模式,用一个中介对象封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

中介者模式包含如下角色:

  • Mediator: 抽象中介者
  • ConcreteMediator: 具体中介者
  • Colleague: 抽象同事类
  • ConcreteColleague: 具体同事类



可以看到两个同事之间没有依赖关系,都是通过中介者进行通信。更具象的一个例子是聊天室,如果不使用中介者模式,可以想象到有多少条依赖关系,而关系越多,每次修改逻辑需要修改的代码就会越多,也越不适宜代码的复用,而通过引入中介者,所有人发的消息只需发送给中介者,中介者再进行转发,那么每个聊天的对象只需要和中介者建立依赖关系即可。


问题解决

回到第一部分的问题上来,我们通过中介者模式来进一步减少对象间的依赖关系。
这里我们在新建 BP_GameState 作为中介者,给其添加OnEnemyKilled两个事件分发器。

在敌人蓝图中,销毁时调用 BP_GameStateOnEnemyKilled 事件分发器

那么在UI和大门中就不需要循环每个敌人来绑定事件,而是通过 BP_GameState 这个中介者来绑定

现在还有个问题就是我们在UI和大门中还是需要获取到所有敌人来设置初始的敌人数,这也不适合当敌人数量会动态增加时的场景。

我们再在 BP_GameState 中增加一个 OnEnemySpawn 事件分发器,在敌人BeginPlay中调用这个事件分发器。

之后在UI和大门中绑定事件,实现敌人数量的增加即可

一个优化就是通过新增一个接口,让BP_GameState来实现接口中的KillEnemyEnemySpawn函数,这样我们在每个敌人对象中就不需要转换为BP_GameState了,这样就算我们以后用了其他的GameState类,下面的代码仍能够复用。


总结

优点

中介者模式的优点:

  • 简化了对象之间的交互。
  • 将各同事解耦。
  • 减少子类生成。
  • 可以简化各同事类的设计和实现。

缺点

中介者模式的缺点

  • 在具体中介者类中包含了同事之间的交互细节,可能会导致具体中介者类非常复杂(臃肿的控制器),使得系统难以维护。

模式应用

MVC架构中控制器,Controller 作为一种中介者,它负责控制视图对象View和模型对象Model之间的交互。当然别忘了这可能会造成Controller特别臃肿。


参考资料

Game Design Pattern —— 中介者模式

【双字精译】虚幻引擎中的设计模式:中介者模式——Ali Elizoheiry|游戏开发游戏编程模式游戏设计模式虚幻蓝图编程事件管理器教程UnrealUE4UE5

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

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

相关文章

Powershell 禁用系统更新

创建一个关闭系统更新脚本 脚本系统兼容10,11,2012,206,2019,2022,2025powershell-install-stop-System-update.ps1 <# Powershell Install stop System update +++++++++++++++++++++++++++++++++++++++++++++++++++++ + _____ _____ _ …

【竞技宝】奥运会:法国国奥VS西班牙国奥

北京时间8月10日法国国奥在巴黎奥运会男足决赛中跟西班牙国奥狭路相逢&#xff0c;这场比赛对于主帅亨利来说&#xff0c;有着极为特殊的意义。因为&#xff0c;亨利将带领法国国奥队冲击他执教生涯首枚奥运会金牌。法国足协邀请亨利出任国奥队主帅&#xff0c;就是希望他能带领…

Mac 连接 Synology NAS【Finder】

对于 Mac 用户&#xff0c;建议使用 Finder 或 Cyberduck 通过WebDAV连接到Synology NAS 在上一篇文章中介绍了如何使用【Cyberduck 】连接到Synology NAS 这一篇文章介绍【Finder】连接到Synology NAS 相关文章&#xff1a; 注重任如何使用 Synology NAS 的套件或其他软件…

纸质文物的数字化革命:RFID技术的应用与影响

在这个数字化的时代&#xff0c;我们见证了技术的革新如何将历史重新点燃。纸质文物&#xff0c;这些人类文明的宝贵篇章&#xff0c;正经历一场由RFID技术引领的革命。 数字化浪潮不仅改变了我们的生活&#xff0c;也重塑了我们保护和传承历史的方式。纸质文物的数字化管理&am…

代码随想录训练营 Day24打卡 回溯算法part03 93. 复原IP地址 78. 子集 90. 子集II

代码随想录训练营 Day24打卡 回溯算法part03 一、 力扣93. 复原IP地址 有效 IP 地址 正好由四个整数&#xff08;每个整数位于 0 到 255 之间组成&#xff0c;且不能含有前导 0&#xff09;&#xff0c;整数之间用 ‘.’ 分隔。 例如&#xff1a;“0.1.2.201” 和 “192.168.1…

扩展【从0制作自己的ros导航小车】C++_ROS_QT5联合编译,简单界面为ROS开发增添交互

从0制作自己的ros导航小车 前言一、环境搭建二、联合编译三、测试 前言 前面已经实现了导航功能&#xff0c;对于之后的一些开发&#xff0c;有交互能力是比较重要的&#xff0c;比如小车上连接一块屏幕&#xff0c;通过屏幕来选择模式&#xff0c;可视化等等。QT是不错的选择…

2024年云计算企业CRM应用与选型研究报告

数字化时代&#xff0c;所有行业都在经历着数字化转型带来的效率革命。在业务流程、协同办公、数据收集和利用、决策方式等诸多方面&#xff0c;在数字化转型的加持下&#xff0c;各行各业的企业都会经历从低效到高效、从无序杂乱到标准化流程和数据驱动决策的成长蜕变。 在IC…

LeetCode 100道题目和答案(一)

1.两数之和 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现。 你可以按…

【安卓】SQLite数据库存储-创建数据库与增删改查

文章目录 创建数据库更新数据库增加数据修改数据删除数据查询数据 安卓专门提供了一个SQLiteOpenHelper帮助类&#xff0c;借助这个类可以非常简单地对数据库进行创建和升级。SQLiteOpenHelper是一个抽象类&#xff0c;使用它需要创建一个自己的帮助类去继承它。SQLiteOpenHelp…

巴黎同款,六自由度技术还原赛场决定性瞬间!

现代纪实摄影大师亨利布列松&#xff0c;曾提出了“决定性瞬间”&#xff08;The Decisive Moment&#xff09;理论——拍摄者捕捉到的画面越稍纵即逝&#xff0c;越难以复制&#xff0c;越宝贵。 很多摄影师的经典作品&#xff0c;都来自那决定性的千分之一秒。 ● 布列松摄于…

OpenCV 读取 MP4 视频

在 C 中结合 OpenCV 库来读取 MP4 视频文件是一个常见的任务。以下是一个简单的示例程序&#xff0c;说明了如何使用 OpenCV 的 VideoCapture 类来打开一个 MP4 文件并逐帧显示每一帧。 VideoCapture::VideoCapture(const string& filename)&#xff1b;参数&#xff1a;f…

一个Android下载网络图片显示并保存到系统相册的完整案例

文章目录 1. 案例简介1.1 效果演示 2. 工程配置3. 网络层3.1 网络接口定义3.2 Retrofit工具类 4. 主界面及完整代码4.1 完整主界面代码 ImageDownloadActivity4.2 布局文件 5. 总结 1. 案例简介 在 Android开发 中&#xff0c;下载图片保存到本地是常见的需求&#xff0c;看似…

一个简单的录音软件(利用QT录音,ffmpeg进行音频重采样,fdk-aac编码)

录音软件是一种非常有用的工具&#xff0c;可以帮助我们记录和存储语音信息。在本文中&#xff0c;我们将介绍一个简单的录音软件&#xff0c;该软件利用QT进行录音&#xff0c;使用ffmpeg进行音频重采样&#xff0c;并使用fdk-aac编码。 一、 环境介绍 1、QT版本: QT5.…

绕过微信电脑版旧版本限制,版本过低不给登录的问题

这张图&#xff0c;对于还在使用低版本微信电脑版的人很熟悉了吧&#xff01;因为微信逐步开始限制低版本的客户端了&#xff0c;导致无法登陆进去。 为什么这么多人还在使用旧版&#xff1f; 因为很多机器人、框架、HOOK版本的微信等等都是在旧版的基础上开发的&#xff0c;…

嘉立创PCB板子降层(从4层到2层实例)

降层导致的改变 走线和连接&#xff0c;若想正常设计先把要用的内容全部移动到其他层。若不使用可以按照下面方式全部删除。 删除定义使用的规则 删除在需要删除层的走线等所有内容

相同的 LLM 在「不同 GPU 上」会产生不同输出?为什么?

编者按&#xff1a; 在大语言模型(LLMs)的部署及其相关的算力扩容过程中&#xff0c;更换 GPU 是否也可能会对模型的输出产生重大影响&#xff1f;这个问题的答案对于确保 LLMs 在不同硬件环境下的一致性和可靠性至关重要。 我们今天为大家带来的这篇文章&#xff0c;作者的核心…

利用docker部署图形化工具 portainer

docker查找图形化工具 Portainer 拉取镜像 docker pull portainer/portainer启动docker UI容器 docker run -d -p 9209:9000 --name portainer --restart always -v /var/run/docker.sock:/var/run/docker.sock -v /opt/data3/mydocker/portainer_data:/data portainer/porta…

MFC多个控件组合存在显示不出来现象

MFC多个控件组合存在显示不出来现象 1、找到rc文件 &#xff0c; 右键查看代码 2、 3、将基础组件放在最前面即可

C++(week16): C++提高:(六) Qt基础

文章目录 零、课前须知一、Qt基础1.CLI与GUI2.事件驱动模型3.Qt快捷键 二、QtCreator1.Qt的安装&#xff1a;Qt框架、IDE2.Qt的六大模式3.核心模块4.布局5.Qt项目中的文件6.信号与槽机制7.添加资源&#xff1a;资源文件qrc8.main.cpp解析(1)ui文件 和 纯代码(2)按钮 信号槽机制…

在嵌入式Linux平台上使用Nginx搭建RTMP流媒体服务器

概述 Nginx是一个以高效稳定著称的高性能的HTTP和反向代理web服务器&#xff0c;它同时也是基于事件驱动开发的异步高性能跨平台服务器。Nginx-RTMP是基于Nginx框架的模块开发&#xff0c;很好地继承了Nginx的异步高性能以及扩展性好的优点。 RTMP 是 Real Time Messaging Pr…