[JS设计模式]Command Pattern

news2024/11/24 15:06:39

文章目录

    • 举例说明
    • 优点
    • 缺点
    • 完整代码

With the Command Pattern, we can decouple objects that execute a certain task from the object that calls the method.

使用命令模式,我们可以将执行特定任务的对象与调用该方法的对象解耦。

怎么理解 执行特定任务的对象 与 调用该方法的对象解耦?

使用命令模式,我们可以将执行特定任务的对象与调用该方法(执行特定任务)的对象解耦。也即将执行调用解耦。

举例说明

Let’s say we have an online food delivery platform. Users can place, track, and cancel orders.

假设我们有一个在线外卖平台。用户可以下订单、跟踪和取消订单。

class OrderManager() {
  constructor() {
    this.orders = []
  }

  placeOrder(order, id) {
    this.orders.push(id)
    return `You have successfully ordered ${order} (${id})`;
  }

  trackOrder(id) {
    return `Your order ${id} will arrive in 20 minutes.`
  }

  cancelOrder(id) {
    this.orders = this.orders.filter(order => order.id !== id)
    return `You have canceled your order ${id}`
  }
}

On the OrderManager class, we have access to the placeOrder, trackOrder and cancelOrder methods. It would be totally valid JavaScript to just use these methods directly!

在OrderManager类中,可以访问placeOrder、trackOrder和cancelOrder方法。直接使用这些方法将是完全有效的JavaScript !

const manager = new OrderManager();

manager.placeOrder("Pad Thai", "1234");
manager.trackOrder("1234");
manager.cancelOrder("1234");

However, there are downsides to invoking the methods directly on the manager instance. It could happen that we decide to rename certain methods later on, or the functionality of the methods change.

直接通过manager实例调用这些方法也有潜在的问题。以后可能决定重命名某些方法,或者这些方法的功能发生了变化。

Say that instead of calling it placeOrder, we now rename it to addOrder! This would mean that we would have to make sure that we don’t call the placeOrder method anywhere in our codebase, which could be very tricky in larger applications. Instead, we want to decouple the methods from the manager object, and create separate command functions for each command!

现在我们将placeOrder重命名为addOrder。这意味着我们必须确保不在代码库的任何地方调用placeOrder方法,这在大型应用程序中可能非常棘手。相反,我们希望将方法与manager对象解耦,并为每个命令创建单独的命令函数!

Let’s refactor the OrderManager class: instead of having the placeOrder, cancelOrder and trackOrder methods, it will have one single method: execute. This method will execute any command it’s given.

让我们重构OrderManager类:代替placeOrdercancelOrdertrackOrder方法,它将只有一个方法:execute。这个方法将执行给定的任何命令。

Each command should have access to the orders of the manager, which we’ll pass as its first argument.

每个命令都应该能够访问管理器的订单,我们将把它作为第一个参数传递给execute

class OrderManager {
  constructor() {
    this.orders = [];
  }

  execute(command, ...args) {
    return command.execute(this.orders, ...args);
  }
}

We need to create three **Command**s for the order manager:

  • PlaceOrderCommand
  • CancelOrderCommand
  • TrackOrderCommand
class Command {
  constructor(execute) {
    this.execute = execute;
  }
}

function PlaceOrderCommand(order, id) {
  return new Command((orders) => {
    orders.push(id);
    return `You have successfully ordered ${order} (${id})`;
  });
}

function CancelOrderCommand(id) {
  return new Command((orders) => {
    orders = orders.filter((order) => order.id !== id);
    return `You have canceled your order ${id}`;
  });
}

function TrackOrderCommand(id) {
  return new Command(() => `Your order ${id} will arrive in 20 minutes.`);
}

Perfect! Instead of having the methods directly coupled to the OrderManager instance, they’re now separate, decoupled functions that we can invoke through the execute method that’s available on the OrderManager.

完美!不是将方法直接耦合到OrderManager实例,它们现在是分离的、解耦的函数,我们可以通过OrderManager上可用的execute方法调用它们。

优点

The command pattern allows us to decouple methods from the object that executes the operation. It gives you more control if you’re dealing with commands that have a certain lifespan, or commands that should be queued and executed at specific times.

命令模式允许我们将方法与执行该方法的对象解耦。如果您正在处理具有特定生命周期的命令,或者应该在特定时间排队并执行的命令,那么它可以为您提供更多的控制。

缺点

The use cases for the command pattern are quite limited, and often adds unnecessary boilerplate to an application.

命令模式的使用场景非常有限,并且经常向应用程序添加不必要的样板代码。

完整代码

class OrderManager {
  constructor() {
    this.orders = [];
  }

  execute(command, ...args) {
    return command.execute(this.orders, ...args);
  }
}

class Command {
  constructor(execute) {
    this.execute = execute;
  }
}

function PlaceOrderCommand(order, id) {
  return new Command(orders => {
    orders.push(id);
    console.log(`You have successfully ordered ${order} (${id})`);
  });
}

function CancelOrderCommand(id) {
  return new Command(orders => {
    orders = orders.filter(order => order.id !== id);
    console.log(`You have canceled your order ${id}`);
  });
}

function TrackOrderCommand(id) {
  return new Command(() =>
    console.log(`Your order ${id} will arrive in 20 minutes.`)
  );
}

const manager = new OrderManager();

manager.execute(new PlaceOrderCommand("Pad Thai", "1234"));
manager.execute(new TrackOrderCommand("1234"));
manager.execute(new CancelOrderCommand("1234"));

请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1327628.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【SpringBoot】之Security进阶使用

🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是君易--鑨,一个在CSDN分享笔记的博主。📚📚 🌟推荐给大家我的博客专栏《SpringBoot开发之Security系列》。&#x1f3af…

解决 Linux git push 贡献者不同(没有出现绿点)的问题

第一步,通过下面的指令,修改 linux git 的配置文件: vi ~/.gitconfig会进入下图界面: 进入本地(Windows)中 git 的设置界面 复制 名称 和 Email 到 gitconfig 里,不要在末尾加 (空…

直排轮滑教程4

蹬地 1,前面练习了蹬地的结构,知道蹬地方向,如何用力。下面来练习具体的蹬地的方法,轮滑蹬地有自己特点。 2,技术方法和特点:蹬地速度快,蹬地有弹性。似跳非跳蹬。 3,四轮着地。轮…

使用PE信息查看工具和Beyond Compare文件比较工具排查dll文件版本不对的问题

目录 1、问题说明 2、修改了代码,但安装版本还是有问题 3、使用PE信息查看工具查看音视频库文件(二进制)的时间戳 4、使用Beyond Compare比较两个库文件的差异 5、找到原因 6、最后 C软件异常排查从入门到精通系列教程(专栏…

NFS原理详解

一、NFS介绍 1)什么是NFS 它的主要功能是通过网络让不同的机器系统之间可以彼此共享文件和目录。 NFS服务器可以允许NFS客户端将远端NFS服务器端的共享目录挂载到本地的NFS客户端中。 在本地的NFS客户端的机器看来,NFS服务器端共享的目录就好像自己的磁…

【蓝桥杯】树的重心

树的重心 图的dfs模板 int dfs(int u) {st[u]true;for(int ih[u];i!-1;ine[i]){int je[i];if(!st[j]){dfs(j);}} }树是这样的。 邻接表: 1: 4->7->2->-1 2: 5->8->1->-1 3: 9->4->-1 4: 6->3->1->-1 5: 2->-1 6: 4->-1 7…

计算机网络 运输层下 | TCP概述 可靠传输 流量控制 拥塞控制 连接管理

文章目录 3 运输层主要协议 TCP 概述3.1 TCP概述 特点3.2 TCP连接RSVP资源预留协议 4 TCP可靠传输4.1 可靠传输工作原理4.1.1 停止等待协议4.1.2 连续ARQ协议 4.2 TCP可靠通信的具体实现4.2.1 以字节为单位的滑动窗口4.2.2 超时重传时间的选择4.2.3 选择确认SACK 5 TCP的流量控…

Python---socket之send和recv原理剖析

1. 认识TCP socket的发送和接收缓冲区 当创建一个TCP socket对象的时候会有一个发送缓冲区和一个接收缓冲区,这个发送和接收缓冲区指的就是内存中的一片空间。 2. send原理剖析 send是不是直接把数据发给服务端? 不是,要想发数据,必须得…

GEE-Sentinel-2月度时间序列数据合成并导出

系列文章目录 第一章:时间序列数据合成 文章目录 系列文章目录前言时间序列数据合成总结 前言 利用每个月可获取植被指数数据取均值,合成月度平均植被指数,然后将12个月中的数据合成一个12波段的时间数据合成数据。 时间序列数据合成 代码…

嵌入式中断理解

一、概念 中断: 在主程序运行过程中,出现了特定的中断触发条件(中断源),使得CPU暂停当前正在运行的程序,转而去处理中断程序,处理完成后又返回原来被暂停的位置继续运行。 中断优先级&#x…

YACS(上海计算机学会竞赛平台)一星级题集——水仙花指数

题目描述 定义一个正整数的十进制表示中各位数字的立方和为它的水仙花指数,给定一个整数 n,请计算它的水仙花指数。 例如 n1234 时,水仙花指数为 输入格式 单个整数:表示 n 输出格式 单个整数:表示 n 的水仙花指…

IPC之九:使用UNIX Domain Socket进行进程间通信的实例

socket 编程是一种用于网络通信的编程方式,在 socket 的协议族中除了常用的 AF_INET、AF_RAW、AF_NETLINK等以外,还有一个专门用于 IPC 的协议族 AF_UNIX,IPC 是 Linux 编程中一个重要的概念,常用的 IPC 方式有管道、消息队列、共…

深入探讨开源对话系统:IntelliQ的世界

在人工智能的快速发展时代,开源项目成为了推动技术革新的重要力量。最近,我注意到了一个特别有趣的项目——IntelliQ。这个项目旨在利用大型语言模型(LLM)构建一个多轮问答系统,不仅具备强大的意图识别和词槽填充&…

【Unity】【WebRTC】如何用Unity而不是浏览器接收远程画面

【背景】 之前几篇我们讨论了如何设置信令服务器,如何发送画面给远端以及如何用浏览器查看同步画面,今天来讨论如何实现Unity内部接收画面。 看本篇之前请先看过之前将web服务器设置和基本远程画面功能的几篇博文。(同专栏下查看&#xff09…

使用VSC从零开始Vue.js——备赛笔记——2024全国职业院校技能大赛“大数据应用开发”赛项——任务3:数据可视化

使用Visual Studio Code(VSC)进行Vue开发非常方便,下面是一些基本步骤: 一、下载和安装Vue 官网下载地址Download | Node.js Vue.js是基于Node.js的,所以首先需要安装Node.js,官网下载地址:No…

PMP项目管理 - 范围管理

系列文章目录 系统架构设计 PMP项目管理 - 整合管理 PMP项目管理 - 质量管理 PMP项目管理 - 采购管理 PMP项目管理 - 资源管理 PMP项目管理 - 风险管理 PMP项目管理 - 沟通管理 现在的一切都是为将来的梦想编织翅膀,让梦想在现实中展翅高飞。 Now everything is …

快速搭建Grafana Promethus 服务器监控系统

该文参考文章,其中又遇到一些问题,并解决,当前主要为了记录一下 探针 Grafana Prometheus 之比 Docker 更简单的部署流程 - 承飞之咎本文重在 Grafana Prometheus 探针 方案的部署流程,介绍和更多使用请到:探针 ̵……

【12.20】转行小白历险记 登录+注册页

一、登录注册页面逻辑 写样式布局:垂直居中、编程式路由、调后端接口正则表达式验证用户输入的密码规则校验通过后,跳转页面js兜底校验调后端接口将token值存储到vuex中,实现持久化存储 vuex不是持久化存储的,如果需要持久化存储…

当下流行的直播技术demo演示

nginx-http-flv-module(更新不是很频繁) SRS: https://ossrs.net/lts/zh-cn/(独立官网,目前最新稳定版version5) 基于SRS搭建直播demo演示: 一、搭建流媒体服务器 参见官网:https://ossrs.ne…

Windows 如何在局域网中建立NTP服务器实现时间同步(设置一台设备作为主机,其他设备作为从机来同步时间)

首先简单了解一下什么是NTP 网络时间协议(NTP)是一种用于同步计算机网络上各设备时间的协议。NTP时间同步在许多项目和应用中都是关键的,特别是那些对时间同步精度有要求的场景。比如需要使用NTP时间同步的情况有:金融交易系统、科学研究实验、工业自动…