[UE5 设计模式] 代理模式Proxy Pattern


参考材料
1. 【UE4 设计模式】策略模式 Strategy Pattern
2. 代理模式
3. UE4游戏逻辑与渲染逻辑分离

1. 概述

1.1 描述

$\cdot$ 在代理模式(Proxy Pattern) 中, 一个类代表另一个类的功能, 这种类型的设计模式属于结构型模式.
$\\$ 代理模式通过引入一个代理对象来控制对原对象的访问. 代理对象在客户端和目标对象之间充当中介, 负责将客户端的请求转发给目标对象, 同时可以在转发请求前后进行额外的处理.
$\\$ 在代理模式中, 我们创建具有现有对象的对象, 以便向外界提供功能接口.

1.2 套路

$\cdot$ 实现方式:
$\\$ 1) 增加中间层: 创建一个代理类, 作为真实对象的中间层.
$\\$ 2) 代理与真实对象组合: 代理类持有真实对象的引用, 并在访问时进行控制.

$\cdot$ 关键代码:
$\\$ 1) 代理类: 实现与真实对象相同的接口, 并添加额外的控制逻辑.
$\\$ 2) 真实对象: 实际执行任务的对象.

$\cdot$ 结构:
$\\$ 主要涉及到以下几个核心角色:
$\\$ 1) 抽象主题(Subject): 定义了真实主题和代理主题的共同接口, 这样在任何使用真实主题的地方都可以使用代理主题.
$\\$ 2) 真实主题(Real Subject): 实现了抽象主题接口, 是代理对象所代表的真实对象. 客户端直接访问真实主题, 但在某些情况下, 可以通过代理主题来间接访问.
$\\$ 3) 代理(Proxy): 实现了抽象主题接口, 并持有对真实主题的引用. 代理主题通常在真实主题的基础上提供一些额外的功能, 例如延迟加载, 权限控制, 日志记录等.
$\\$ 4) 客户端(Client): 使用抽象主题接口来操作真实主题或代理主题, 不需要知道具体是哪一个实现类.

1.3 使用场景

$\cdot$ 当需要在访问一个对象时进行一些控制或额外处理时.

1.4 优缺点

$\cdot$ 优点:
$\\$ 1) 职责分离: 代理模式将访问控制与业务逻辑分离.
$\\$ 2) 扩展性: 可以灵活地添加额外的功能或控制.
$\\$ 3) 智能化: 可以智能地处理访问请求, 如延迟加载, 缓存等.

$\cdot$ 缺点:
$\\$ 1) 性能开销: 增加了代理层可能会影响请求的处理速度.
$\\$ 2) 实现复杂性: 某些类型的代理模式实现起来可能较为复杂.

2. UE5实践

虚幻引擎的框架设计的一个基本思路是: 游戏逻辑与渲染逻辑分离.
$\\$ 即存在一个游戏的世界: 包含在场景中的Actor(及与其关联的ActorComponent). 同时, 与存在一个渲染的世界, 这个世界中包含了呈现游戏世界所需要的信息.
$\\$ 渲染的世界如同布景一般, 其只会呈现在当前摄像机范围内的, 可以被渲染的内容.
$\\$ 例如: 一个AStaticMeshActor及其包含UStaticMeshComponent组件对应游戏的世界, 不会去处理渲染相关的逻辑, 而是通过一个FStaticMeshSceneProxy场景代理对象来执行渲染.
$\\$ 任何一个可以被渲染的组件, 都需要调用CreateSceneProxy()来创建对应的SceneProxy(场景代理) 对象. 注: CreateSceneProxy在组件注册到世界中的时候被调用, 而不是每帧都调用.

2.1 游戏线程和渲染线程代表

游戏线程的对象通常做逻辑更新, 在内存中有一份持久的数据, 为了避免游戏线程和渲染线程产生竞争条件, 会在渲染线程额外存储一份内存拷贝, 并且使用的是另外的类型. 如Game Thread上的UPrimitiveComponent对应于Render Thread上的FPrimitiveSceneProxy.
$\\$ 游戏线程代表一般由游戏游戏线程操作, 渲染线程代表主要由渲染线程操作. 如果尝试跨线程操作数据, 将会引发不可预料的结果, 产生竞争条件.
$\\$ 这些场景代理FPrimitiveSceneProxy本属于引擎模块, 但又属于渲染线程专属对象, 说明它们是连接游戏线程和渲染线程的桥梁, 是线程间传递数据的工具人; 这些图元几何体的场景代理, 是UPrimitiveComponent在渲染器的代表, 镜像了UPrimitiveComponent在渲染线程的状态.

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注