概述

描述

  • 将一个请求封装为一个对象,从而使我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。

  • 命令模式是一种对象行为型模式,其别名为动作(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的更多相关文章

  1. 设计模式 - 命令模式(command pattern) 多命令 具体解释

    命令模式(command pattern) 多命令 具体解释 本文地址: http://blog.csdn.net/caroline_wendy 參考命令模式: http://blog.csdn.ne ...

  2. 设计模式 - 命令模式(command pattern) 具体解释

    命令模式(command pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 命令模式(command pattern) : 将请求封装成对 ...

  3. 设计模式 - 命令模式(command pattern) 宏命令(macro command) 具体解释

    命令模式(command pattern) 宏命令(macro command) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy 參考: 命名模式(撤销) ...

  4. 设计模式 - 命令模式(command pattern) 撤销(undo) 具体解释

    命令模式(command pattern) 撤销(undo) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 參考命令模式: http://blog.cs ...

  5. C#设计模式——命令模式(Command Pattern)

    一.概述通常来说,“行为请求者”与“行为实现者”是紧耦合的.但在某些场合,比如要对行为进行“记录.撤销/重做.事务”等处理,这种无法抵御变化的紧耦合是不合适的.在这些情况下,将“行为请求者”与“行为实 ...

  6. 乐在其中设计模式(C#) - 命令模式(Command Pattern)

    原文:乐在其中设计模式(C#) - 命令模式(Command Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 命令模式(Command Pattern) 作者:webabcd ...

  7. 二十四种设计模式:命令模式(Command Pattern)

    命令模式(Command Pattern) 介绍将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可取消的操作. 示例有一个Message实体类,某个 ...

  8. 设计模式-15命令模式(Command Pattern)

    1.模式动机 在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计,使 ...

  9. 设计模式----行为型模式之命令模式(Command Pattern)

    下面来自head first设计模式的命令模式一章节. 定义 将"请求"封装成对象,以便使用不同的请求.队列或者日志来参数化其他对象.命令模式也支持可撤销的操作. 类图 注: 1. ...

随机推荐

  1. 20210716 noip17

    考场 终于有一场在晚上考了 T1 随便画了画就发现要求每个点的后继个数,想起来有 dfs 和 toposort 两种方法,感觉很稳 T2 裸的网络流有 70pts?!真香 一看 T3 就想起了 Mst ...

  2. openswan框架和编译时说明

    刚开始学习openswan项目代码时,自己尝试了在虚拟机上编译.安装.运行openswan代码,由于当时刚开始学习openswan代码,因此对于其构成并不清楚,在编译.运行过程中有了问题,基本是通过百 ...

  3. 《微服务架构设计模式》读书笔记 | 第8章 外部API模式

    目录 前言 1. 外部API的设计难题 1.1 FTGO应用程序的服务及客户端 1.2 FTGO移动客户端API的设计难题 1.3 其他类型客户端API的设计难题与特点 2. API Gateway模 ...

  4. footer沉底效果

    介绍一个简单直接的方法: flex布局 heml,body{ height: 100%; min-height: 100%; display: flex; flex-direction: column ...

  5. golang 判断平台是32位还是64位

    在strconv包中有个常量 const intSize  =  32  <<  (  ^uint(0)  >>  63  ) const IntSize = intSize ...

  6. CodeForce-811B Vladik and Complicated Book(水题)

    http://codeforces.com/problemset/problem/811/B 题意: 给定一个长度为 N 不重复的数字序列,然后对其进行 M 次询问. 每次询问含L,R,X三个值,问如 ...

  7. 一个简单的session传值学习

    a.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...

  8. java线程day-01

    综述:下面写的是我学习java线程时做的一些笔记和查阅的一些资料总结而成.大多以问答的形式出现. 一.什么是线程? 答:线程是一个轻量级的进程,现在操作系统中一个基本的调度单位,而且线程是彼此独立执行 ...

  9. 关于python如何构造测试数据

    参考资料:https://www.cnblogs.com/miaoxiaochao/p/13234589.html 一.Faker模块是什么? 一个Python第三方模块,主要用来创建伪数据 无需再手 ...

  10. django ORM教程(转载)

    Django中ORM介绍和字段及字段参数   Object Relational Mapping(ORM) ORM介绍 ORM概念 对象关系映射(Object Relational Mapping,简 ...