关于命令模式我所知道的

关键词: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>)
} 

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

来看下类似的功能的demo:

通过命令模式改造后:

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

定义

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

类比日常生活

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

那份订单就是命令。

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

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

图片来源于 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(); 

最后

整理了一套《前端大厂面试宝典》,包含了HTML、CSS、JavaScript、HTTP、TCP协议、浏览器、VUE、React、数据结构和算法,一共201道面试题,并对每个问题作出了回答和解析。

有需要的小伙伴,可以点击文末卡片领取这份文档,无偿分享

部分文档展示:



文章篇幅有限,后面的内容就不一一展示了

有需要的小伙伴,可以点下方卡片免费领取

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值