在讲解命令模式之前我们先来了解一个生活中的命令模式场景:

场景1:

医院看病抓药:

当你因为肾虚到医院看医生,医生一番操作之后得出结论:要吃个疗程【夏桑菊】、【小柴胡】(药名纯属虚构,真的肾虚就找医生),于是医生开了个药单【夏桑菊、小柴胡】,让你拿着药单到收费窗口;于是射射发抖的到收费窗口把药单【夏桑菊、小柴胡】给到收费人员,收费人员不管给你看医生的是谁,你是否得肾虚,他只要对着药单得收费项进行收费,完成后在药单上盖个收费章,然后让你拿着药单到取药窗口拿药,于是你又跑到取药窗口,将药单【夏桑菊、小柴胡】给到工作人员,工作人员到各个药柜找到你要得药给到你。

场景2:

后厨制作:

当你来到一家餐厅吃饭,你跟服务员说你要吃【韭菜、秋葵、生蚝】,于是服务员将写在订单纸【韭菜、秋葵、生蚝】,把它插到后厨窗口,大厨们拿到订单纸【韭菜、秋葵、生蚝】,之后红红哈嘿把菜做好。

相信你很容易从上面的案例中z找到共同点,他们的工作模式。

对于场景一:

  • 医生:他并不知道给你收费的是谁,怎么收费,也不知道谁给你拿药,怎么找到药。他就知道给你一张药单。
  • 收费人:他并不知道是给你的药单,他只需要按照药单上面写着的给你结账,也不管你下一步要做什么。
  • 取药人:他并不知道给你看到医生是谁,给你结账的是谁,只要药单上盖了章,就给你拿药。

    -你 :携带者药单,到处找人办事,你也不管收费人是怎么给你收的,也不关心取药人怎么找到药,你只需要将药单交给他们。他们就知道怎么做了

对于场景2:

  • 你:你不用纠结谁给你做的菜,谁给你下的单,你就提出你的需求。
  • 服务员:根据你的需求生成张订单,然后给到后厨,不关心后厨怎么做菜。
  • 厨师:不关心吃的人是谁,服务员是谁,只需要拿到订单,做出菜品。

总结:大家都只关注到【单子/命令】,而不关心其他人是怎么做的。

引用《JavaScript设计模式及与开发实践》中的原话:

命令模式最常见的应用场景:有时候需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道请求的操作是什么,此时希望有一种松耦合的方式来设计程序,使得请求发送者与请求接收者能够消除彼此之间的耦合关系。

用场景2的例子套入原话:有时候【顾客】需要向【厨师】发送请求【吃生蚝...】,但【顾客】实际上并不知道请求【吃生蚝】是哪个厨师做的(甚至生蚝在隔壁店的厨师帮忙都有可能),也不知道【厨师】接到请求【吃生蚝】之后他会怎么做出这道菜,此时希望有一个中间人【服务员】帮忙处理【顾客】跟【厨师】的关系,使得【顾客】跟【厨师】没有产生耦合关系。而【服务员】是负责将【顾客】请求命令带给【厨师】。

场景2案例如何代码实现:

首先我们要理清楚这种模式涉及到的角色:

由三种角色构成:

  • 发布者 invoker(发出命令,持有命令对象)
  • 接收者 receiver (命令处理者,不知道谁发起请求)
  • 命令 command(接收命令,分发给对应接收者处理,持有接收者)

首先我们来讲解一个非常简单的案例:

  // 案例 

  // 接受者
class Receiver {
execute () {console.log('处理')};
}
// 命令
class Command {
constructor (receiver) {
this.receiver = receiver;
}
execute () {
this.receiver.execute();
}
}
// 发布者
class Invoker {
constructor (command) {
this.command = command;
}
invoke () {
this.command.execute();
};
}
// 执行
let command = new Command(new Receiver());
let invoker = new Invoker(command);
invoker.invoke();

结合到案例2的场景当中:

  // 厨师 拥有各项才艺
class Cook {
makeVegetables () {
console.log('make vegetable');
return 'vegetable';
}
makeFish () {
console.log('make fish');
return 'fish';
}
execute () {
this.makeFish();
this.makeVegetables();
}
}; // 命令对象
class Command {
constructor (cook) {
this.cook = cook;
}
execute () {this.cook.execute};
} // 服务员 命令的发布者
class Waiter {
constructor (command) {
this.command = command;
}
invokeCommand () {
this.command.execute();
};
}

其实在js中函数作为一等公民,能够随意传递的来讲,有更加简化代码的方式:

  // 案例 ------------------------------ js 简化 -----------------------------------------

  class Receiver  {
execute () {console.log('执行逻辑')};
}
class Invoker {
invoke (receiver) {
receiver.execute();
};
}
let invoker = new Invoker();
invoker.invoke(new Receiver());

我还是更加推荐上面的写法,至少看起来更加清晰的结构,命令模式的使用更加易懂。

宏命令

是一组命令的集合,通过执行宏命令的方式,可以一次执行一组命令。

场景:如果你家里买了很多小米的智能家电,你希望一下班回来就自动都打开灯,打开空调,播放音乐...;这岂不美哉。

  // 案例 ------------------------------ 宏命令 -----------------------------------------

  // 定义命令
class OpenLightCommand {
execute() {
console.log('open light');
}
}
class PlayMusicCommand {
execute() {
console.log('play light');
}
}
class OpenAirConditioningCommand {
execute() {
console.log('open air conditioning');
}
} // 命令集合
class MacroCommand {
constructor() {
this.commandList = [];
}
add(command) {
this.commandList.push(command);
}
clear() {
this.commandList = [];
}
execute() {
for (let i = 0; i < this.commandList.length; i++) {
this.commandList[i].execute();
}
}
} class ITMan {
constructor(command) {
this.commamd = command;
}
whenGoHome() {
this.commamd.execute();
}
} let macroCommand = new MacroCommand();
macroCommand.add(new OpenLightCommand());
macroCommand.add(new PlayMusicCommand());
macroCommand.add(new OpenAirConditioningCommand()); let itMan = new ITMan(macroCommand);
itMan.whenGoHome();

总结:这种模式的写法跟策略模式有很大的相似性,但目的性却完全不同。命令模式更多的是为了解决请求方与实现方的解耦。

JavaScript设计模式之命令模式【命令解耦】的更多相关文章

  1. javascript设计模式详解之命令模式

    每种设计模式的出现都是为了弥补语言在某方面的不足,解决特定环境下的问题.思想是相通的.只不过不同的设计语言有其特定的实现.对javascript这种动态语言来说,弱类型的特性,与生俱来的多态性,导致某 ...

  2. JavaScript设计模式之----组合模式

    javascript设计模式之组合模式 介绍 组合模式是一种专门为创建Web上的动态用户界面而量身制定的模式.使用这种模式可以用一条命令在多个对象上激发复杂的或递归的行为.这可以简化粘合性代码,使其更 ...

  3. 从ES6重新认识JavaScript设计模式(三): 建造者模式

    1 什么是建造者模式? 建造者模式(Builder)是将一个复杂对象的构建层与其表示层相互分离,同样的构建过程可采用不同的表示. 建造者模式的特点是分步构建一个复杂的对象,可以用不同组合或顺序建造出不 ...

  4. javascript设计模式学习之九——命令模式

    一.命令模式使用场景及定义 命令模式常见的使用场景是:有时候需要向某些对象发送请求,但是并不知道请求的接受者是谁,也不知道请求的具体操作是什么.此时希望用一种松耦合的方式来设计程序,使得请求的发送者和 ...

  5. java设计模式--行为型模式--命令模式

    命令模式 概述 将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可撤消的操作. 适用性 .抽象出待执行的动作以参数化某对象. .在不同的时刻指定.排 ...

  6. JavaScript设计模式之建造者模式

    一.建造者模式模式概念 建造者模式可以将一个复杂的对象的构建与其表示相分离,使得同样的构建过程可以创建不同的表示.也就是说如果我们用了建造者模式,那么用户就需要指定需要建造的类型就可以得到它们,而具体 ...

  7. JavaScript设计模式之构造函数模式

    一.构造函数模式概念 构造函数用于创建特定类型的对象——不仅声明了使用过的对象,构造函数还可以接受参数以便第一次创建对象的时候设置对象的成员值.你可以自定义自己的构造函数,然后在里面声明自定义类型对象 ...

  8. JavaScript设计模式之工厂模式

    一.工厂模式概念 工厂模式定义一个用于创建对象的接口,这个接口由子类决定实例化哪一个类.该模式使一个类的实例化延迟到了子类.而子类可以重写接口方法以便创建的时候指定自己的对象类型(抽象工厂). 这个模 ...

  9. JavaScript设计模式之代理模式

    一.代理模式概念 代理,顾名思义就是帮助别人做事,GoF对代理模式的定义如下: 代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问.代理模式使得代理对象控制具体对象的引用.代理几乎可 ...

  10. javascript设计模式——职责链模式

    前面的话 职责链模式的定义是使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止.职责链模式的名字非常形象,一 ...

随机推荐

  1. SOLID:面向对象设计的前五项原则

    S.O.L.I.D是Robert C. Martin提出的前五个面向对象设计(OOD)原则的首字母缩写,他更为人所熟知的名字是Uncle Bob.   将这些原理结合在一起,可使程序员轻松开发易于维护 ...

  2. Django---博客项目实战

    1.urls from django.conf.urls import url from django.contrib import admin from blog import views urlp ...

  3. Spring Data JPA根据属性名查询

    https://blog.csdn.net/chengqiuming/article/details/82528961

  4. webapp项目新建java class、webapp目录树结构

      上一篇中我们介绍了IDEA.maven新建webapp项目的两种方式,分别是:在命令行中用模板创建.直接在IDEA中选择骨架创建. 但都存在一个问题:目录树不完整.有些人会不知道接下来该如何创建j ...

  5. VMware 虚拟机开机黑屏解决方法

    # 调整VMware硬盘启动优先级 第一步:打开电源时进入固件,也就是BIOS 设置界面. 第二步:找到Main-最下面的Boot-time Diagnostic Screen,敲“Enter”,弹出 ...

  6. Python创建一个爬虫项目===从零开始哟!想说的下次 要不要出一期关于pycharm与Python之间的合作

    当然,不用爬虫框架,也是可以的 比如说 beauitfulsoup xml http 就可以完美的得到一个爬虫的解决方案! 个人的意思是,新手或者刚入门的可以考虑以上的方式进行练习后 在使用框架 首先 ...

  7. 还在纠结学什么编程语言吗?Python可能会“教”你做人

    这几年为什么Python在中国就火起来了? Python这个东西国,大概是从2017年末开始,突然就火了起来的.此前,对于Python,乃至编程,绝大多数程度上都是专业人士的话题,在普通大众层面上起不 ...

  8. 最全总结!聊聊 Python 发送邮件的几种方式

    1. 前言 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很多已经做案例的人,却不知道如何去学习更加高深的知识.那么针对这三类人,我给大 ...

  9. 我用python远程探查女友每天的网页访问记录,她不愧是成年人!

    利用Python制作远程查看别人电脑的操作记录,与其它教程类似,都是通过邮件返回. 利用程序得到目标电脑浏览器当中的访问记录,生产一个文本并发送到你自己的邮箱,当然这个整个过程除了你把python程序 ...

  10. 《SOD框架企业级应用数据架构实战》新书简介和预定

    SOD框架“企业级”应用数据架构实战 ----致敬平凡的程序员! 历时两年写成, 两大MVP: 张善友. 刘冰(宇内流云) JAVA技术专家 申毅 联合推荐! 10年磨一剑:汇聚作者超过10年的架构工 ...