关于命令模式我所知道的

简介: 关于命令模式我所知道的

image.png


本文已参与「新人创作礼」活动,一起开启掘金创作之路。

关键词:Command

本质其实就是回调函数。

在没有函数的语言里,命令模式就是函数的替代品(代餐、平替)。

主要作用:拓展业务功能,通过发送命令来解耦执行任务的方法。

最核心的实现手段:把函数当作参数进行传递。


命令模式解决什么问题?


前端开发很多情况下需要通过后端提供的数据,例如后端返回一组按钮的数据。

{
  "btns": [
    {
      "code": "submit",
      "disable": false
    },
    {
      "code": "valid",
      "disable": false
    },
    {
      "code": "cancel",
      "disable": false
    }
  ]
}


我们第一反应是:将按钮遍历,然后在点击事件的时候添加相关的业务逻辑:

const btnsTextMap = {
  submit: '提交',
  valid: '校验',
  cancel: '取消'
}
const onHandle = (code) => {
  if(code === 'submit') {
    // ...
  }
  // ...
}
{
  btns.map(btn => <button onClick={()=>onHandle(item.code)}>{btnsTextMap[btn[item.code]]}</button>)
}


image.png

后续如果增加新按钮例如:删除。那就需要修改 onHandle 里面的函数,这样其实并不易维护。

来看下类似的功能的demo:


image.png

通过命令模式改造后:


image.png



通过调用 execute 把要执行的方法当做参数传入,就可以直接执行相关逻辑。


定义


将请求转换为一个包含与请求相关的所有信息的独立对象。能根据不同的请求,将方法参数化、 延迟请求执行或将其放入队列中, 且能实现可撤销操作。


类比日常生活


在餐厅点餐,选好菜品叫服务员下单。厨师收到订单,根据订单配料做菜,然后将做好的菜品放在托盘上,服务员看到托盘后对订单进行检查, 确保所有食物都是你要的, 然后将食物放到了你的桌上。

那份订单就是命令。

拿订餐来说,我需要向厨师发送请求,但是完全不知道厨师的名字和联系方式,也不知道厨师炒菜的方式和步骤。

命令模式把我的订单封装成 command 对象,也就是订餐中的订单对象。厨师只是把拿到的订单执行特定的业务逻辑。


image.png


图片来源于 refactoringguru


应用场景


命令模式可以解决哪类问题

主要是用来控制命令的执行,比如:异步、延迟、排队执行命令、撤销重做命令、存储命令、给命令记录日志等。

命令模式的作用不仅是封装运算块,而且可以很方便地给命令对象增加撤销操作。就像订餐时客人可以通过电话来取消订单一样。


具体实现


命令模式的设计思路和具体实现。

命令模式用到最核心的实现手段,就是将函数封装成对象。把函数当作参数进行传递。

interface Command {
  execute(): void;
}
class SimpleCommand implements Command {
  private payload: string;
  constructor(payload: string) {
    this.payload = payload;
  }
  public execute(): void {
    console.log(
      `SimpleCommand: See, I can do simple things like printing (${this.payload})`
    );
  }
}
class ComplexCommand implements Command {
  private receiver: Receiver;
  private a: string;
  private b: string;
  constructor(receiver: Receiver, a: string, b: string) {
    this.receiver = receiver;
    this.a = a;
    this.b = b;
  }
  public execute(): void {
    console.log(
      "ComplexCommand: Complex stuff should be done by a receiver object."
    );
    this.receiver.doSomething(this.a);
    this.receiver.doSomethingElse(this.b);
  }
}
class Receiver {
  public doSomething(a: string): void {
    console.log(`Receiver: Working on (${a}.)`);
  }
  public doSomethingElse(b: string): void {
    console.log(`Receiver: Also working on (${b}.)`);
  }
}
class Invoker {
  private onStart: Command;
  private onFinish: Command;
  public setOnStart(command: Command): void {
    this.onStart = command;
  }
  public setOnFinish(command: Command): void {
    this.onFinish = command;
  }
  public doSomethingImportant(): void {
    console.log("Invoker: Does anybody want something done before I begin?");
    if (this.isCommand(this.onStart)) {
      this.onStart.execute();
    }
    console.log("Invoker: ...doing something really important...");
    console.log("Invoker: Does anybody want something done after I finish?");
    if (this.isCommand(this.onFinish)) {
      this.onFinish.execute();
    }
  }
  private isCommand(object): object is Command {
    return object.execute !== undefined;
  }
}
const invoker = new Invoker();
invoker.setOnStart(new SimpleCommand("Say Hi!"));
const receiver = new Receiver();
invoker.setOnFinish(new ComplexCommand(receiver, "Send email", "Save report"));
invoker.doSomethingImportant();

image.png

参考资料:

refactoringguru


目录
相关文章
|
存储 分布式计算 Hadoop
Hadoop【基础知识 01】【分布式文件系统HDFS设计原理+特点+存储原理】(部分图片来源于网络)
【4月更文挑战第3天】Hadoop【基础知识 01】【分布式文件系统HDFS设计原理+特点+存储原理】(部分图片来源于网络)
597 3
|
8月前
|
人工智能 搜索推荐 机器人
grok官网是什么?这次一定要记好了!GROK3官网入口
grok官网是什么?这次一定要记好了!GROK3官网入口
|
12月前
|
机器学习/深度学习 人工智能 运维
智能化运维:提升IT系统管理效率的新范式####
在数字化转型加速的今天,企业IT系统的复杂性日益增加,传统的运维模式已难以满足高效、稳定的业务需求。本文探讨了智能化运维(AIOps)如何通过融合人工智能、大数据分析和自动化工具,重塑IT运维流程,显著提升管理效率和服务质量,为企业带来前所未有的运营洞察力和响应速度。 ####
|
10月前
|
人工智能 运维 监控
评测报告:AI驱动的操作系统服务套件体验
评测报告:AI驱动的操作系统服务套件体验
167 3
|
存储 程序员 编译器
C语言标识符的深入探究
C语言标识符的深入探究
346 1
|
搜索推荐 SEO
外贸业务客户开发「途径详情」
扩大找客户的各种途径和方法,例如通过skype. facebook, google. B2B平台、展会,外贸开发客户软件,广交会买家数据,或者是通过海关数据找客户。
355 0
|
Python
Python if语句语法
Python中if语句的语法
229 0
|
SQL 数据可视化 关系型数据库
搭建微信公众号管理系统
常言道 PHP 是世界上最好的语言(手动滑稽)。这次我再在 LAMP 环境中搭建一个微信公众号管理系统。充分利用这个环境。这次使用的服务器应用程序是 微擎 安装方法非常简单,马上进入正题吧!
336 0
|
存储 数据库 开发工具
小微企业阿里云最佳实践系列(三):OSS 图片存储(对象存储)与 CDN 内容分发
本博文主要为大家介绍静态文件的存储以及使用 CDN 加速访问的热点图片。很多企业都会面临网站大图加载缓存、文件下载并发低(通常同时几个人下载服务器上的大文件就会跑满服务的带宽)等问题,本文将逐一为大家讲解如何解决此类问题。
8017 0
|
机器学习/深度学习
机器学习系列直播--使用对抗神经网络(GANs)生成猫【8月30日 20点不见不散】
对抗神经网络模型(GANs)作为当下最火的神经网络模型 使用GANs我们可以还原图像原始颜色 可以还原马赛克: 可以把漫画变成真实图像 可以把文字变成图像 还可以进行视频下一帧预测.
5176 0