• JavaScript设计模式——命令模式


    命令模式,指的是执行特定操作的指令
    命令模式将请求与实现解耦并封装成独立对象,从而使不同的请求对客户端的实现参数化。

    命令模式的应用场景

    命令模式最常见的应用场景是:向对象发送请求,但是不知道想请求的接收者是谁,也不知道接收的请求是什么,因此需要通过一种松耦合的方式来设计程序。

    拿订餐来说,客人需要向厨师发送请求,但是完全不知道这些厨师的名字和联系方式,也不知道厨师炒菜的方式和步骤。命令模式把客人订餐的请求封装成command对象,也就是订餐中的订单对象。这个对象可以在程序中被四处传递,就像订单可以从服务员手中传到厨师的手中。这样一来,客人不需要知道厨师的名字,从而解开了请求调用者和请求接收者之间的耦合关系

    相对于过程化的请求调用,command对象拥有更长的生命周期。对象的生命周期是跟初始请求无关的,因为这个请求已经被封装在了command对象的方法中,成为了这个对象的行为。我们可以在程序运行的任意时刻去调用这个方法,就像厨师可以在客人预定1个小时之后才帮他炒菜,相当于程序在1个小时之后才开始执行command对象的方法。

    基本结构

    命令模式的实现:将具体的业务逻辑封装成对象,对象暴露一个参数化的接口,通过调用这个接口并传递参数实现调用命令对象中的一些方法。

    命令模式包含一个command对象和execute函数,execute函数用来执行具体的命令方法,command对象用来存储各种命令。

    let command = (function (){
    	let Command = {
    		display(){}
    	};
    	return function execute(commandName, ...args){
    		Command[commandName].call(this, ...args);
    	}
    })();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    为了更加方便也可以让命令模式一次执行多条命令

    function execute(commands){
    	if(commands.length){
    		for(let i = 0; i < commands.length; i++){
    		let command = commands[i];
    			Command[command.commandName].call(Command, ...command.params);
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    这种一组命令的集合叫做宏命令,通过执行宏命令的方式,一次可以执行一批命令。

    示例:绘图命令

    我们在使用canvas绘图的时候经常会调用内置方法,这个时候就会经常使用canvas上下文,这在多人开发项目中是耦合度较高的,如果某个人修改了canvas上下文,那么后果是无法估计的,常用的做法是将canvas上下文的引用封装在命令对象内部,如果某人想绘图,直接通过命令对象调用一条命令即可。

    let canvasCommand = (function (){
    	const canvas = document.getElementbyId('canvasId');
    	const ctx = canvas.getContext('2d');
    	const Command = {
    		fillStyle(style){
    			ctx.fillStyle = style;
    		},
    		fillRect(x,y,width,height){
    			ctx.fillRect(x,y,width,height);
    		}
    	};
    	return function execute(commands){
    	if(commands.length){
    		for(let i = 0; i < commands.length; i++){
    		let command = commands[i];
    			Command[command.commandName].call(Command, ...command.params);
    		}
    	}
    }
    )();
    canvasCommand([{commandName:'fillRect', params:[0,0,100,100]}])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    上面的代码将canvas上下文封装在命令对象内部,不被外部访问,保护canvas上下文不会被修改,同时暴露对应的绘图接口给外部,可以通过命令的形式绘图。

    优缺点

    优点

    • 降低系统的耦合度,命令迷失能将调用操作的对象与实现该操作的对象解耦
    • 增加或删除命令非常方便,采用命令模式增加与删除命令不会影响其他类,它满足开闭原则,对扩展比较灵活
    • 可以实现宏命令,命令模式可以与组合模式结合,将多个命令配成一个组合,即宏命令
    • 方便实现undo和redo操作,命令模式可以与备忘录模式结合,实现命令的撤销与恢复

    缺点

    • 使用命令模式可能会导致某些系统有过多的命令类
    • 系统结构更加复杂
  • 相关阅读:
    S7-200SMART PLC Modbus TCP通信(多服务器多从站轮询)
    批处理修改win10密码以及密码提示
    铸造工艺问题1
    【JavaEE】Java的文件IO
    【SpringCloud】LoadBalance负载均衡服务调用快速入门
    C++设计模式——Bridge模式(下)
    Android问题笔记 - 关于Error type 3
    Onedev v7.4.14 路径遍历漏洞分析(CVE-2022-38301)
    多家饮料企业进入暖饮市场,APS智能排产在饮料行业的应用
    基于微信JAVA后台校园小程序系统设计与实现 开题报告
  • 原文地址:https://blog.csdn.net/qq_40850839/article/details/122349545