【UE4 设计模式】命令模式 Command Pattern
概述
描述
将一个请求封装为一个对象,从而使我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。
命令模式是一种对象行为型模式,其别名为动作(Action)模式或事务(Transaction)模式。
建造者模式将客户端与包含多个组成部分的复杂对象的创建过程分离,客户端无需知道复杂对象的内部组成与装配方式,主需要知道所需的建造者即可。类似工厂方法,但是建造者模式返回一个完整的复杂产品,而抽象工厂模式则返回一系列相关的产品。以汽车为例,工厂方法可以看成不同汽车配件的生成,而建造者模式则可以看成时汽车的组装

套路
- 客户端 Client
命令的发起者。确定接下来要执行什么命令。 - 调用者 Invoker
命令的管理者,不关心每个命令具体是做什么内容,根据客户端的指示按序执行命令。 - 抽象命令 Command
命令接口协议,确定每个命令需要提供的功能,这里要求每个命令类都提供执行方法。 - 具体命令 ConcreteCommand
包含执行一个命令所需的所有上下文信息,例如执行接收者的哪个方法,以及方法所需要的参数,甚至命令作为GUI 显示时的相关信息,例如应该显示的图标路径。具体命令类是命令模式中的核心节点,需要重点理解。 - 接收者 Receiver:命令所对应任务的实际执行者,位于调用链条的末端。
使用场景
- 系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。
- 系统需要在不同的时间指定请求、将请求排队和执行请求。
- 系统需要将一组操作组合在一起,即支持宏命令
- 示例
- 按键、快捷键映射、玩家输入
- 撤销(Undo)、恢复(Redo),维护命令列表
- 新手引导
优缺点
- 优点
- 降低系统的耦合度。
- 新的命令可以很容易地加入到系统中。
- 可以比较容易地设计一个命令队列和宏命令(组合命令)。
- 可以方便地实现对请求的Undo和Redo。
- 缺点
- 使用命令模式可能会导致某些系统有过多的具体命令类。因为针对每一个命令都需要设计一个具体命令类,因此某些系统可能需要大量具体命令类,这将影响命令模式的使用。
UE4 实践
写一个事件触发器,点击地图地点触发场景传送;点击资料片播放过场动画
创建接收者抽象类、具体类 —— 场景传送、触发剧情
- 此处抽象类非必要,但实际使用可能会有多个派生类多种 action 成员函数被使用
// 抽象接收者类 Receiver
UCLASS()
class DESIGNPATTERNS_API UCmdReceiver : public UObject
{
GENERATED_BODY()
public: virtual void Action() { check(0 && "You must override this"); }
}; // 具体接收者类 Receiver —— 场景传送
UCLASS()
class DESIGNPATTERNS_API ULevelPortal : public UCmdReceiver
{
GENERATED_BODY()
public:
virtual void Action() override {
UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" 传送到下一个场景"));
}
}; // 具体接收者类 Receiver —— 资料片播放
UCLASS()
class DESIGNPATTERNS_API UCutscene : public UCmdReceiver
{
GENERATED_BODY()
public:
virtual void Action() override {
UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" 播放剧情动画"));
}
};
抽象命令类、具体命令类 —— 场景传送命令、资料片播放命令
- 此处 接收者 采用了继承方式,因此和具体命令搭起来,代码显得重复。实际使用时,Execute成员函数可能会重载,调用不同类对象进行处理
// 抽象命令类
UCLASS(Abstract)
class DESIGNPATTERNS_API UCommand : public UObject
{
GENERATED_BODY()
public: void SetReceiver(UCmdReceiver* pCmdReceiver) { m_pCmdReceiver = pCmdReceiver; } // 调用接收者的 Action
virtual void Execute() {
if (m_pCmdReceiver)
{
m_pCmdReceiver->Action();
}
}
// virtual void undo() protected:
UCmdReceiver *m_pCmdReceiver;
}; // 具体命令类 —— 场景传送命令
UCLASS()
class DESIGNPATTERNS_API UPortalCommand : public UCommand
{
GENERATED_BODY()
public: // 可重载做些额外的工作
//virtual void Execute() override { }
}; // 具体命令类 —— 资料片播放命令
UCLASS()
class DESIGNPATTERNS_API UCutsceneCommand : public UCommand
{
GENERATED_BODY()
public: // 可重载做些额外的工作
//virtual void Execute() override { }
};
调用者 Invoker
UCLASS()
class DESIGNPATTERNS_API ACommandActor : public AActor
{
GENERATED_BODY()
public: void BeginPlay() override { // 创建接收者 场景传送
ULevelPortal* LevelPortal = NewObject<ULevelPortal>(); // 创建命令对象
UPortalCommand* PortalCommand = NewObject<UPortalCommand>();
PortalCommand->SetReceiver(LevelPortal); // this 当做调用者 Invoker
PortalCommand->Execute(); // 创建接收者 资料片播放
UCutscene* Cutscene = NewObject<UCutscene>(); // 创建命令对象
UCutsceneCommand* CutsceneCommand = NewObject<UCutsceneCommand>();
CutsceneCommand->SetReceiver(Cutscene); // this 当做调用者 Invoker
CutsceneCommand->Execute();
}
};
调式输出
LogTemp: Warning: ULevelPortal::Action 传送到下一个场景
LogTemp: Warning: UCutscene::Action 播放剧情动画
参考
【UE4 设计模式】命令模式 Command Pattern的更多相关文章
- 设计模式 - 命令模式(command pattern) 多命令 具体解释
命令模式(command pattern) 多命令 具体解释 本文地址: http://blog.csdn.net/caroline_wendy 參考命令模式: http://blog.csdn.ne ...
- 设计模式 - 命令模式(command pattern) 具体解释
命令模式(command pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 命令模式(command pattern) : 将请求封装成对 ...
- 设计模式 - 命令模式(command pattern) 宏命令(macro command) 具体解释
命令模式(command pattern) 宏命令(macro command) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy 參考: 命名模式(撤销) ...
- 设计模式 - 命令模式(command pattern) 撤销(undo) 具体解释
命令模式(command pattern) 撤销(undo) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 參考命令模式: http://blog.cs ...
- C#设计模式——命令模式(Command Pattern)
一.概述通常来说,“行为请求者”与“行为实现者”是紧耦合的.但在某些场合,比如要对行为进行“记录.撤销/重做.事务”等处理,这种无法抵御变化的紧耦合是不合适的.在这些情况下,将“行为请求者”与“行为实 ...
- 乐在其中设计模式(C#) - 命令模式(Command Pattern)
原文:乐在其中设计模式(C#) - 命令模式(Command Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 命令模式(Command Pattern) 作者:webabcd ...
- 二十四种设计模式:命令模式(Command Pattern)
命令模式(Command Pattern) 介绍将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可取消的操作. 示例有一个Message实体类,某个 ...
- 设计模式-15命令模式(Command Pattern)
1.模式动机 在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计,使 ...
- 设计模式----行为型模式之命令模式(Command Pattern)
下面来自head first设计模式的命令模式一章节. 定义 将"请求"封装成对象,以便使用不同的请求.队列或者日志来参数化其他对象.命令模式也支持可撤销的操作. 类图 注: 1. ...
随机推荐
- Django——session保持登录
Django操作session语法: # 1.设置Sessions值 request.session['session_name'] ="admin" # 2.获取Sessions ...
- string类型数据的操作指令
1. 2. 3. 4. 5. 6. 7. 8. 9. 从右到左是索引从-1开始 10. 11. 12. 13. 14. 15.
- Abp Vnext3 vue-admin-template(一用户登录)
Git地址https://github.com/PanJiaChen/vue-admin-template/blob/master/README-zh.md 官方文档https://panjiache ...
- 原子操作cas
一.概念, 基于处理器指令,把比较和交换合成一个指令完成,保证了原子性: 因为是针对一个内存地址值的,一个内存地址指向一个变量,所以只对一个共享变量能保证原子性: 二.原子操作类 锁只有synchro ...
- JDBC基础和使用
内存泄漏意思就是内存越来越少了,因为垃圾太多: 线程泄露就是线程池中线程越来越少,执行过程中异常,没有返回给线程池,线程池中线程越来越少: 一.概念 二.快速入门 三.JDBC各个类详解 1.driv ...
- Django学习day08随堂笔记
今日考题 """ 今日考题 1.聚合查询,分组查询的关键字各是什么,各有什么特点或者注意事项 2.F与Q查询的功能,他们的导入语句是什么,针对Q有没有其他用法 3.列举常 ...
- Jmeter系列(15)- 常用断言之大小断言
大小断言 大小断言验证响应数据size大小,它的作用范围有主Sample与子Sample:适用场景,判断附件下载的大小,比如项目安装包 完整响应:全部响应信息 响应头:响应头信息,比如http协议的头 ...
- GoLang设计模式07 - 责任链模式
责任链模式是一种行为型设计模式.在这种模式中,会为请求创建一条由多个Handler组成的链路.每一个进入的请求,都会经过这条链路.这条链路上的Handler可以选择如下操作: 处理请求或跳过处理 决定 ...
- wordpress 搭建
wordpress 搭建: 公司要使用自建地图.选用了国外的Mapplic .但是Mapplic不支持直接编辑地图,需要用json的格式定义.但是wordpress版本的就有这个鬼东西,所以搞了一个这 ...
- P6775-[NOI2020]制作菜品【贪心,dp】
正题 题目链接:https://www.luogu.com.cn/problem/P6775 题目大意 \(n\)种原材料,第\(i\)个有\(d_i\)个,\(m\)道菜品都需要\(k\)个原料而且 ...