UE开发中的设计模式(二) —— 中介者模式
上一篇文章介绍了观察者模式如何降低观察者和目标之间的耦合,并通过一个实例具体实现了观察者模式,本篇文章从上篇文章的实例继续,介绍中介者模式是如何带来对象间进一步的松耦合。
文章目录
- 问题提出
- 概述
- 问题解决
- 总结
- 优点
- 缺点
- 模式应用
- 参考资料
问题提出
上篇文章用一个实例介绍了观察者模式,具体就是场景中有多个敌人,有一个UI文本显示场景中的剩余敌人数,还有一个大门,当敌人被消灭完后打开。那么当敌人死亡时,就需要发布通知,而UI文本和大门就会收到消息执行相关流程。
我们通过观察者模式实现了敌人并不需要知道订阅者的信息,只需要简单地发布通知即可,具体对订阅者进行通知是通过抽象的目标。下面分析下还存在什么问题,看下面大门的蓝图,可以看到大门还是需要获取敌人对象数组,以设置敌人数量和绑定接收通知的事件。同样UI中也需要相同的操作,这样带来的问题一个是,订阅者依赖发布者的信息造成耦合,另一个是每有一个新的订阅者都需要先获取到所有敌人,但其实想一想这个信息是共享的,要是能只获取到一次就完美了。

这时引出中介者模式(Mediator Pattern)解决这些问题。
概述
中介者模式也是一种行为型模式,用一个中介对象封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
中介者模式包含如下角色:
- Mediator: 抽象中介者
- ConcreteMediator: 具体中介者
- Colleague: 抽象同事类
- ConcreteColleague: 具体同事类


可以看到两个同事之间没有依赖关系,都是通过中介者进行通信。更具象的一个例子是聊天室,如果不使用中介者模式,可以想象到有多少条依赖关系,而关系越多,每次修改逻辑需要修改的代码就会越多,也越不适宜代码的复用,而通过引入中介者,所有人发的消息只需发送给中介者,中介者再进行转发,那么每个聊天的对象只需要和中介者建立依赖关系即可。
问题解决
回到第一部分的问题上来,我们通过中介者模式来进一步减少对象间的依赖关系。
这里我们在新建 BP_GameState 作为中介者,给其添加OnEnemyKilled两个事件分发器。
在敌人蓝图中,销毁时调用 BP_GameState 的 OnEnemyKilled 事件分发器

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

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

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

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


总结
优点
中介者模式的优点:
- 简化了对象之间的交互。
- 将各同事解耦。
- 减少子类生成。
- 可以简化各同事类的设计和实现。
缺点
中介者模式的缺点
- 在具体中介者类中包含了同事之间的交互细节,可能会导致具体中介者类非常复杂(臃肿的控制器),使得系统难以维护。
模式应用
MVC架构中控制器,Controller 作为一种中介者,它负责控制视图对象View和模型对象Model之间的交互。当然别忘了这可能会造成Controller特别臃肿。
参考资料
Game Design Pattern —— 中介者模式
【双字精译】虚幻引擎中的设计模式:中介者模式——Ali Elizoheiry|游戏开发游戏编程模式游戏设计模式虚幻蓝图编程事件管理器教程UnrealUE4UE5
相关文章:
UE开发中的设计模式(二) —— 中介者模式
上一篇文章介绍了观察者模式如何降低观察者和目标之间的耦合,并通过一个实例具体实现了观察者模式,本篇文章从上篇文章的实例继续,介绍中介者模式是如何带来对象间进一步的松耦合。 文章目录 问题提出概述问题解决总结优点缺点模式应用 参考资…...
安卓应用开发学习:聚合数据API获取天气预报
一、引言 上个月我通过腾讯位置服务,实现了手机定位应用的开发学习。最近在看软件书籍时,又看到了聚合数据API方面的内容。 书上介绍了聚合数据天气预报API的应用,不过书上的代码看得有些难受,我到聚合数据官网,对天气…...
设计模式 - 抽象工厂模式
💝💝💝首先,欢迎各位来到我的博客,很高兴能够在这里和您见面!希望您在这里不仅可以有所收获,同时也能感受到一份轻松欢乐的氛围,祝你生活愉快! 文章目录 引言一、抽象工…...
塔子哥选数字-阿里淘天2024笔试(codefun2000)
题目链接 塔子哥选数字-阿里淘天2024笔试(codefun2000) 题目内容 塔子哥有一个长为n的数组a。他定义一个数组的权值为:数组中不同的数字个数。 塔子哥希望从数组a中选出在个数子,使得这k个数字组成的数组权值最大,请你帮帮塔子哥。 输入描述…...
【leetcode】杨辉三角(Java语言描述)
杨辉三角 给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中,每个数是它左上方和右上方的数的和。 示例 1: 输入: numRows 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]示例 2: 输入: numRows 1 输出: [[1]] …...
Vue - 关于vue-kinesis 移动动画组件
Vue - 关于vue-kinesis 移动动画组件 vue-kinesis可以根据鼠标移动或滚动条来控制元素动画的动画效果;除此之外,vue-kinesis 还可以设置音频文件,根据音频频率来控制动画的跳动效果。 一、安装vue-kinesis Vue2版本: 1.安装 …...
leetCode- - - 链表
目录 1.反转链表(leetcode206) 2. 链表内指定区间反转(leetcode92) 3.链表中的节点每k个一组翻转(leetcode25) 4.合并两个排序的链表(leetcode21) 5.链表的中间节点(…...
Ashok:一款多功能开源网络侦查OSINT工具
关于Ashok Ashok是一款多功能开源网络侦查公开资源情报OSINT工具,该工具可谓是OSINT领域中的瑞士军刀,广大研究人员可以使用该工具轻松完成网络侦查任务。 侦察是渗透测试的第一阶段,这意味着在计划任何实际攻击之前收集信息。因此ÿ…...
没有获取淘宝API的资质怎么获取淘宝数据
淘宝是头部电商平台之一,每个自研商家或电商软件服务商想要开发电商管理功能模板就少不了要对接淘宝API。淘宝API是在淘宝开放平台提供的,自研商家和软件服务商接入淘宝开放平台需要经过一系列审核和申请流程,要求资质和相关资料符合对应的要…...
SQL手工注入
目录 1.判断是否存在sql注入点 1.1我们在地址栏中输入?id1 1.2我们在地址栏中输入?id-- 2.联合查询 2.1首先知道表格有几列,如果报错就是超过列数,如果显示正常就是没有超出列数。 2.2爆出显示位,就是看看表格里面哪一列是在页面显示…...
【SQL】大的国家
目录 题目 分析 代码 题目 World表: ---------------------- | Column Name | Type | ---------------------- | name | varchar | | continent | varchar | | area | int | | population | int | | gdp | bigint | ----…...
8月5日学习笔记 glibc安装与安全用户角色权限
一,glibc安装 https://www.mysql.com/ 官⽹ https://downloads.mysql.com/archives/community/ https://downloads.mysql.com/archives/get/p/23/file/mysql-8.0.33-li nux-glibc2.12-x86_64.tar 安装步骤 1.安装依赖库 [rootlocalhost ~]# yum list installed |g…...
DrissionPage 一个替代selenium的pip --- 一个可以接管正在运行的chrome包
DrissionPage 一个替代selenium的pip包,持续更新 1、加载内容,并接管chrome浏览器 from DrissionPage import ChromiumPage, ChromiumOptions page ChromiumPage(addr_or_opts127.0.0.1:9222) print(page.title)ul page.eles(idform-submit) for i i…...
爬虫入门--了解相关工具
目录 1.爬虫与python 2.第一个爬虫 3.web请求的全过程 3.1服务器渲染 3.2前端JS渲染 4.浏览器工具 4.1Elements 4.2Console 4.3Source 4.4network(重点) 5.小结 1.爬虫与python 首先我们要知道,爬虫一定要用Python么? 非也~…...
django项目中通用的分页组件
文章目录 分页组件pager组件代码 分页组件 应用分页组件,需要以下两个步骤: 视图函数中:(先获取queryset,将request和queryset传入分页组件对象中,得到生成的html标签) def customer_list(requ…...
想实现ubuntu搭建sqli-labs靶场
目录 首先前期的nginx和php部署完成编辑编辑 Xftp导入sqli-labs 遇到了的问题 它提示我们请检查db-creds.inc 去尝试解决这个问题 尝试修改MySQL root密码 修改db-creds.inc配置 再次尝试依旧失败 思考:会不会是MySQL版本过高的原因 重新下载MySQL5.7.…...
tp8 按日期分组查出数据
1.如果数据库里时间字段都是时间戳,使用mysql中的from_unixtime()函数 field("from_unixtime(create_time,%Y-%m-%d) as time,group_concat(id)")->group(time)->select()2. 如果数据库是普通的日期格式(如2024-01-02 01:23:50)&#x…...
单例模式(懒汉模式,饿汉模式)
单例的饿汉模式:在主函数未调用之前该单例就已经存在了,所以不存在线程安全的问题。 class Singleton { private: Singleton(){} public:static Singleton s1;static Singleton* GetInstance(){return &s1;}Singleton(const Singleton&) delet…...
【Qt】Item Widgets 多元素控件
Qt中提供的多元素控件有: QListWidgetQListViewQTableWidgetQTableViewQTreeWidgetQTreeView 上述控件分为Widget和View,其区别如下: 以QTableWidget和QTableView为例 QTableView是基于MVC(Model-View-Controller)设计的控件。QTableView自身…...
sharded_inference_engine:MLXDynamicShardInferenceEngine;step
目录 sharded_inference_engine:MLXDynamicShardInferenceEngine 类属性 方法 __init__(self) async def infer_prompt(self, shard: Shard, prompt: str, inference_state: Optional[str] = None) -> (np.ndarray, str, bool) async def infer_tensor(self, shard: …...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
DAY 47
三、通道注意力 3.1 通道注意力的定义 # 新增:通道注意力模块(SE模块) class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...
聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
如何为服务器生成TLS证书
TLS(Transport Layer Security)证书是确保网络通信安全的重要手段,它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书,可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...
2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...
