【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. ...
随机推荐
- 第18章-x86指令集之常用指令
x86的指令集可分为以下4种: 通用指令 x87 FPU指令,浮点数运算的指令 SIMD指令,就是SSE指令 系统指令,写OS内核时使用的特殊指令 下面介绍一些通用的指令.指令由标识命令种类的助记符( ...
- 菜鸟入门Linux之路(方法论浅谈)
Linux是为人熟知的OS之王,已"统治"世界.要想学好绝非易事. 作为菜鸟,可以与Linux亲密接触的方法很多,如视频.书籍.各种企培资料等等,如今的在线教育也如火如荼. 总结说 ...
- git02
Git Gui的使用 Ssh key 介绍及使用 Ssh key介绍 我理解的就是每台电脑上会产生出一个ssh key,然后自己有一个远程账户,但是自己有可能有很多台电脑, 包括家里的电脑还有公司的电 ...
- MongoDB(2)- 安装 MongoDB
MacOS 安装 MongoDB 博主目前都用 mac 电脑练习,所以这里重点讲 MacOS 安装方式 系统要求 MongoDB 4.4 社区版支持 macOS 10.13 或更高版本 安装 Home ...
- Git 系列教程(10)- 仓库别名
Git 别名 前言 Git 并不会在你输入部分命令时自动推断出你想要的命令 如果不想每次都输入完整的 Git 命令,可以通过 git config 文件来轻松地为每一个命令设置一个别名 $ git c ...
- openswan协商流程之(一):main_outI1()
主模式第一包:main_outI1() 1. 序言 main_outI1()作为主模式主动发起连接请求的核心处理函数,我们可以通过学习该函数的处理流程来探究openswan中报文封装的基本思想.如果之 ...
- Lombok中@Data注解的坑
开发遇到@Data注解的大坑 如果使用@Data注解,会默认重写hashcode和equals方法 那会遇到什么问题呢? 比如说: @Data public class DataTest { priv ...
- 微信公众号jssdk分享接口onMenuShareAppMessage自定义的参数无效,微信分享失败原因
使用jssdk为jweixin-1.4.0.js updateTimelineShareData,安全域名接口也设置正确,可就是分享,转发朋友圈不成功. 解决方案:采用<script src=& ...
- 测试验收标准checklist
需求实现功能清单 功能实现目的 需求改造功能清单 关联功能清单 关联系统 端到端全流程场景 业务联系性场景 业务全流程场景 上下需求关联规则 业务角度在流程中关注项 财报.评级 授信方案 反洗钱 面向 ...
- python 建站教程
主端:安装nginx uwsgi django pymysql mysql安装mysql到http://repo.mysql.com/里面找 mysql57-community-release-el7 ...