首页 > 其他分享 >设计模式之命令模式

设计模式之命令模式

时间:2023-12-12 21:25:17浏览次数:32  
标签:... ClearCommand 菜单 模式 命令 Command passState 设计模式 options

1. 定义

将一个请求封装成一个对象,从而允许客户端参数化不同的请求、将请求排队或者记录请求日志、以及支持可撤销的操作

2. 口语化表述

假设某餐厅的工作流程如下:

  • 顾客在大堂点餐,服务员记录菜单
  • 服务员将菜单送到后厨
  • 后厨根据菜单做菜
  • 服务员根据菜单送到对应的餐桌

在这个场景中,后厨不需要了解顾客做了什么,顾客不需要关心后厨做了什么,只需要按照菜单来做事情

假设顾客在点完餐后又想更改,只需要服务员更改一下对应的菜单即可

这种模式就是命令模式,这里的菜单就是一个请求对象,包含了请求信息

(下面的表述会沿用这个场景)

3. 源码示例

Cesium.js是一个著名的、基于WebGL的GIS前端框架

基于WebGL就不得不提WebGL(OpenGL)的基础概念,比如VAO(顶点数组对象)、VBO(顶点缓冲对象)、Shader Program(着色器)等

每一次渲染,通常都需要执行一系列的WebGL命令(WebGL是个全局状态机,需要使用GL命令控制),如 gl.clearColor(清屏)、gl.draw(绘制)等

Cesium.js在渲染模块中,将GL命令封装为Command对象

Cesium中的Command对象包含执行的指令参数和执行方法,比如最简单的ClearCommand

function ClearCommand(options) {
  // ...
  this.color = options.color;
  this.depth = options.depth;
  this.stencil = options.stencil;
  this.renderState = options.renderState;
  this.framebuffer = options.framebuffer;
  this.owner = options.owner;
  this.pass = options.pass;
}
 
ClearCommand.prototype.execute = function (context, passState) {
  context.clear(this, passState);
};
 

ClearCommand包含颜色、深度、通道等指令参数和执行方法context.clear(this, passState)

context.clear()会执行清除的WebGL指令:

Context.prototype.clear = function (clearCommand, passState) {
  // ...
  const c = clearCommand.color;
  const d = clearCommand.depth;
  const s = clearCommand.stencil;
 
  gl.clearColor(c.red, c.green, c.blue, c.alpha);
  gl.clearDepth(d);
  gl.clearStencil(s);
 
  bindFramebuffer(this, framebuffer);
  gl.clear(bitmask);
};

ClearCommand在Scene中的调用流程是:

初始化Scene时初始化ClearCommand

function Scene(options) {
  // ...
  this._clearColorCommand = new ClearCommand({
    color: new Color(),
    stencil: 0,
    owner: this,
  });
  // ...
}

执行更新时调用ClearCommandexecute()方法

Scene.prototype.updateAndExecuteCommands = function (passState, backgroundColor) {
    // ...
    updateAndClearFramebuffers(this, passState, backgroundColor);
    // ...
};
function updateAndClearFramebuffers(scene, passState, clearColor) {
  // ...
  // Clear the pass state framebuffer.
  const clear = scene._clearColorCommand;
  Color.clone(clearColor, clear.color);
  clear.execute(context, passState);
  // ...
}

这么设计的好处是,Command对象可以存储各种参数信息,这些信息也可以随时更改,并且,这个命令在在需要调用时只需要执行自己的execute方法

具体的Command(如,ClearCommand)只需要根据参数做事情,Scene对象只需要保存这些参数并在需要时执行Command的execute方法

缺点呢,存储Command对象需要内存开销,开发时封装Command对象需要时间

4. 总结

4.1 设计优点

  • 开闭原则

    新来的顾客只需要添加菜单即可,新来的厨师只需要处理菜单即可

  • 单一职责原则

    顾客、厨师只负责做自己的事情

  • 实现操作的拦截或者延迟执行

    菜单传递到后厨并没有立刻做出菜品,所以顾客可以修改菜单,厨师也可以提前做准备

4.2 适用场景

  • 通过操作来参数化对象

    将命令封装为一个对象,可以实时改变它的状态

  • 将操作放入队列中、操作的执行或者远程执行操作

  • 实现操作回滚功能

    即撤销上一步命令

5. 参考资料

[1] 命令设计模式 (refactoringguru.cn)

[2] Cesium渲染模块之Command - 当时明月在曾照彩云归 - 博客园 (cnblogs.com)

标签:...,ClearCommand,菜单,模式,命令,Command,passState,设计模式,options
From: https://www.cnblogs.com/jiujiubashiyi/p/17897196.html

相关文章

  • openGauss学习笔记-155 openGauss 数据库运维-备份与恢复-导出数据-使用gs_dump和gs_d
    openGauss学习笔记-155openGauss数据库运维-备份与恢复-导出数据-使用gs_dump和gs_dumpall命令导出数据-概述155.1概述openGauss提供的gs_dump和gs_dumpall工具,能够帮助用户导出需要的数据库对象或其相关信息。通过导入工具将导出的数据信息导入至需要的数据库,可以完成数据库......
  • Redis进阶命令
    1.设置过期时间expire[keyName][seconds]eg:expirefoo60再次使用expire命令会重置键的过期时间。2.查看剩余过期时间ttl[keyName]eg:ttlfoottl表示timetolive3.使用事务连续执行一系列命令multi[command1][command2]...exec 4.排序可以对l......
  • Linux文件复制命令SCP
    scp命令:scp可以实现远程主机之间的文件复制,scp使用ssh协议,所以双方必须开启ssh后方能使用常用选项:-r:复制目录时使用-P:大写的P指定端口,远程主机未改端口号可省略,[email protected]:/tmp/111.jpg/Users/rkhd/Downloads/zhang *SCP获取远程主机上的文......
  • Python实现单例模式的五种写法
    单例模式是一种设计模式,用于确保一个类只有一个实例,并提供全局访问点。在Python中,可以使用多种方法实现单例模式。本文将介绍五种常见的Python单例模式实现方式,包括使用模块、装饰器、基类、元类和线程安全机制。单例模式是一种常见的设计模式,用于确保一个类只有一个实例,并提供全局......
  • 筑基-Windows&Linux常用命令
    1.针对文件管理和字符处理cdL切换目录~当前用户家目录~username特定用户的家目录-工作区切换前的上一个目录.当前目录..上一级目录cdW切换目录.当前目录..上一级目录不加参数显示当前所在目录路径pwdL显示当前工作目录lsL显示目录内容-a显......
  • 策略模式(strategy)
    1#include<iostream>2usingnamespacestd;34//设计思想:我们父类和子类就是一个扩展的关系?是不是合适5//里氏代换原则:子类对象就应该能完全替代父类的行为6//对于继承这样设计,特别小心,我们:组合大于继承7//把quack和fly抽象成为一个对象,那么这个问题......
  • liunx系统sed命令使用
    增sed'$行数i新增内容'文件名在文件里某行上面新增内容sed'$行数a新增内容'文件名在文件里某行下面新增内容-i.bak对源文件进行修改并备份修改之前源文件#在文件里第5行上面插入cccccc内容[root@VM-Project_Test/project]#sed'5icccccc'note_txt1234ccccc......
  • Linux常用命令
    前言本文意在记录平时在linux系统中的常用命令,还有一些常用软件(比如:nginx、redis、mysql等)的常用命令。以提高自己平常开发效率,因为有的时候会突然忘记。......
  • kvm virsh常用命令
    #查看已启动虚机[root@localhostdriver]#virshlistIdNameState----------------------------------------------------3ttt2running5ttt3running#查看所有虚机......
  • 设计模式之单例模式:不同实现方式的深度解析
    什么是单例模式单例模式是一种常用的软件设计模式,其主要作用是保证某一个类只能有一个实例,并提供对该实例的全局访问点。单例模式有三个要点:1.某个类只能有一个实例。2.它必须自行创建这个实例。3.它必须自行向整个系统提供这个实例。单例模式的分类单例设计模式在具体实现......