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

相关推荐
Zane19945 天前
一个 new 就能创建对象,为什么还要拆出单例、工厂、建造者、原型四种模式?
设计模式
怕浪猫6 天前
一行命令复刻爆款视频,我把 Hypit 从安装跑到了出片
人工智能·设计模式·程序员
Zane19946 天前
函数式编程里的函数,其实不是你天天写的那个函数——三大编程范式的边界在哪
设计模式
Zane19948 天前
策略模式现在该不该上?一次讲清楚过度设计和设计不足怎么找平衡
设计模式
她说..8 天前
常见设计模式-模板方法模式
java·spring·设计模式·springboot
xiaofeiyang1508 天前
第六章 · 桥接 — 三支毛笔,画出九种颜色
设计模式
归真仙人8 天前
【UE项目迁移银河麒麟(Linux)局域网会话搜索失败排查】
ue5·ue4·vr·unreal engine·银河麒麟
Shadow(⊙o⊙)9 天前
OTOL设计模式 One Thread One Loop
服务器·网络·设计模式
sarasuki9 天前
如何让LLM 能在半夜偷偷打开网易云呢?
人工智能·设计模式·agent
小王师傅669 天前
【设计模式】装饰模式(四):框架源码实战——从 Java I/O 到 Spring 到 MyBatis
java·设计模式