命令模式:请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找能够处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。
生活小栗子:客户下单,订单记录了客户购买的产品,仓库根据订单给客户备货。javascript
命令模式由三种角色构成:java
invoker
(发出命令,调用命令对象,不知道如何执行与谁执行);receiver
(提供对应接口处理请求,不知道谁发起请求);command
(接收命令,调用接收者对应接口处理发布者的请求)。发布者 invoker
和接收者 receiver
各自独立,将请求封装成命令对象 command
,请求的具体执行由命令对象 command
调用接收者 receiver
对应接口执行。git
命令对象 command
充当发布者 invoker
与接收者 receiver
之间的链接桥梁(中间对象介入)。实现发布者与接收之间的解耦,对比过程化请求调用,命令对象 command
拥有更长的生命周期,接收者 receiver
属性方法被封装在命令对象 command
属性中,使得程序执行时可任意时刻调用接收者对象 receiver
。所以 command
可对请求进行进一步管控处理,如实现延时、预约、排队、撤销等功能。github
class Receiver { // 接收者类 execute() { console.log('接收者执行请求'); } } class Command { // 命令对象类 constructor(receiver) { this.receiver = receiver; } execute () { // 调用接收者对应接口执行 console.log('命令对象->接收者->对应接口执行'); this.receiver.execute(); } } class Invoker { // 发布者类 constructor(command) { this.command = command; } invoke() { // 发布请求,调用命令对象 console.log('发布者发布请求'); this.command.execute(); } } const warehouse = new Receiver(); // 仓库 const order = new Command(warehouse); // 订单 const client = new Invoker(order); // 客户 client.invoke(); /* 输出: 发布者发布请求 命令对象->接收者->对应接口执行 接收者执行请求 */
有时候须要向某些对象发送请求,可是并不知道请求的接收者是谁,也不知道被请求的操做是什么。须要一种松耦合的方式来设计程序,使得发送者和接收者可以消除彼此之间的耦合关系。
——《JavaScript 设计模式与开发实践》
优势:算法
缺点:设计模式
宏命令:一组命令集合(命令模式与组合模式的产物)
发布者发布一个请求,命令对象会遍历命令集合下的一系列子命令并执行,完成多任务。缓存
// 宏命令对象 class MacroCommand { constructor() { this.commandList = []; // 缓存子命令对象 } add(command) { // 向缓存中添加子命令 this.commandList.push(command); } exceute() { // 对外命令执行接口 // 遍历自命令对象并执行其 execute 方法 for (const command of this.commandList) { command.execute(); } } } const openWechat = { // 命令对象 execute: () => { console.log('打开微信'); } }; const openChrome = { // 命令对象 execute: () => { console.log('打开Chrome'); } }; const openEmail = { // 命令对象 execute: () => { console.log('打开Email'); } } const macroCommand = new MacroCommand(); macroCommand.add(openWechat); // 宏命令中添加子命令 macroCommand.add(openChrome); // 宏命令中添加子命令 macroCommand.add(openEmail); // 宏命令中添加子命令 macroCommand.execute(); // 执行宏命令 /* 输出: 打开微信 打开Chrome 打开Email */
傻瓜命令:命令对象须要接收者来执行客户的请求。智能命令:命令对象直接实现请求,不须要接收者,“聪明”的命令对象。微信
“傻瓜命令” 与 “智能命令” 的区别在因而否有 “接收者” 对象。this
// openWechat 是智能命令对象,并无传入 receiver 接收对象 const openWechat = { execute: () => { // 命令对象直接处理请求 console.log('打开微信'); } };
没有 “接收者” 的智能命令与策略模式很相似。代码实现相似,区别在于实现目标不一样。spa
参考文章
本文首发Github,期待Star!
https://github.com/ZengLingYong/blog
做者:以乐之名 本文原创,有不当的地方欢迎指出。转载请指明出处。