命令模式

菜鸟教程中代理模式总结)

1.定义:将请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令
的合适的对象,并把该命令传给相应的对象,该对象执行命令。
2.主要解决:行为请求者与行为实现者通常是一种紧耦合的关系,为了消除这种耦合关系
3.何时使用:命令执行过程较为复杂且可能存在变化,需要对执行命令动作本身进行额外操作,
此时可以考虑使用命令模式
4.如何解决:通过调用者调用接受者执行命令,顺序:调用者→接受者→命令。
5.关键代码:定义三个角色:1、received 真正的命令执行对象 2、Command(命令) 3、invoker 使用命令对象的入口
  • 解释
1.站在主要解决上举个例子:比如电视它具有开和关的功能,用代码来表示的话就是一个'电视类'有两个方法'开电视',
           '关电视'。一般执行的时候'电视.开电视',对应上面说的'主要解决来讲'开电视这个行为和开电视这个实现
            都是电视来做的两者是在一起
2.站在定义上:这时候遥控器出现了,'开/关电视'的行为请求。可以看做两个命令,并且将这两个命令单独写成对象
              现在就多了两个对象'开电视' 和'关电视'他们是一组命令,多了个'遥控器'可以调用这些命令,并且把这些命令
              给了电视,电视依旧还是有'开电视', '关电视'的方法,不过不是直接请求调用而是遥控器间接调用了
   

优缺点

  • 优点
1.Invoker(调用者)的存在使命令执行之前有了更多的设计空间(日志记录、命令回滚、拒绝执行命令、命令队列等)
2.对命令进行封装,使命令易于扩展和修改
3.命令发出者和接受者解耦,使发出者不需要知道命令的具体执行过程即可执行
  • 缺点
1、使用命令模式可能会导致某些系统有过多的具体命令类。

使用场景

认为是命令的地方都可以使用命令模式,比如:
1、GUI 中每一个按钮都是一条命令。
2、模拟 CMD。

延伸不错的讲解命令模式文章

文章一什么是命令模式图解

参考地址

1.假设现在有个请求处理,正常操作客户端直接调用请求处理的类
  • 类似解释中没有遥控器的电视
1.引入命令模式后客户端的请求发送类和请求处理类之间增加一个Invoker类,再将请求发送类发送
的所有请求封装成对象,然后让Invoker(调用者)类去管理这些请求对象,并决定这些请求是否允许
执行、何时执行、按什么顺序执行。

2.好处:由于在请求发送类和请求处理类之间增加了请求转发者,因此这两个类之间的藕合度就大大降低。
3.分析图:'Infvoker (调用者) 遥控器','Command(命令)开机/关机','Receiver(接受者)就是电视类里面有开关机方法'
  • 命令模式的类图

对命令模式的划分

命令模式

  • 文章中的类图
  • 文章中的说明
Client : 即请求发出者,通过调用Invoker方法发出请求。
Invoker : 请求的调用者,内部持有具体请求的引用。
ConcreteCommand :封装的请求对象,内部持有Receiver对象。
Receiver:请求接受者,根据请求对象的指挥进行不同的反应。

前端命令模式

1.书中举了一个例子,现在有个需求有十个按钮,让两个人来写,一个人负责按钮的绘制工作,
一个人负责写这个按钮点击后的具体行为封装到对象中

2.根据命令模式分析这个需求,参照上面'文章一什么是命令模式图解',可以发现'写按钮的一方是客户端',
写这些'按钮事件功能的对应图中的请求处理类',为了想让他俩解耦画按钮的如果比写逻辑的先完成,
我又不想读你的'事件触发的代码'等你写完后在加到和我按钮关联,这时候使用'命令模式'达到解耦

3.书上先说了命令模式的'场景':
       有时候需要向某些对象发送请求,但是并不知道'请求的接收者是谁','也不知道被请 求的操作是什么',
    此时希望用一种松耦合的方式来设计软件,使得请求发送者和请求接 收者能够消除彼此之间的耦合关系。
根据这个场景书中的得到的'理由':
     点击了按钮之后,必须向某些'负责具体行为的对象发送请求','这些对象就是请求的接收者'。
   但是目前并'不知道接收者是什么对象','也不知道 接收者究竟会做什么'。此时我们需要借助命令对象的帮助,
   以便解开按钮和负责具体行为对象之 间的耦合。

根据上面分析实现代码

1.首先需要一个'Receiver' 请求的接受者,简单的理解这里面有上面所有按钮的'具体行为动作'
2.需要一个'ConcreteCommand ' 是每一个单独指令,这些单独指令对象中都有'Receiver'对象,
他们都会有一个共同的方法(在java 或者是ts中甚至es6我们会吧这个共同的方法定义在一个接口中)
3.需要一个'Invoker'请求的调用者,他将会具体调用某个指令对象(有点像代理模式,但区别是他的
调用方法不用像代理模式那样需要和被代理对象实现名字一样的方法)
  • 代码实现
1.下面代码中的'Receiver' -- MenuBar 和 SubMenu 他们有所有按钮的具体行为动作
2.'ConcreteCommand ' -- 'RefreshMenuBarCommand','AddSubMenuCommand ','DelSubMenuCommand '
这些对象是将'Receiver' 中的每个具体行为拆分开来,他们都有一个特定,内部都有'Receiver'
也就是请求接受者的对象,有一个共同的方法'execute' 来调用这些'Receiver'中与之匹配的方法
3.'Invoker' -- 'setCommand' 也就是请求调用者,他们会接受'ConcreteCommand' 对象并且 调用他们
4.命令都有同一接口实现为什么这么做看'execute'方法
<html>
<head>
    <meta charset="utf-8">
</head>
<body>
    <button id="button1">点击按钮1</button>
    <button id="button2">点击按钮2</button>
    <button id="button3">点击按钮3</button>
</body>
<script>
    // 1.菜单这些执行方法拆出来的命令,封装成对象会有个参数(要请求的对象--电视)
    // 2.要控制 遥控器(调用者)(调用那个对象,那个方法)
    // 3.拆除命令的对象(请求者)也就是电视机
    var button1 = document.getElementById('button1')
    var button2 = document.getElementById('button2')
    var button3 = document.getElementById('button3')
    // 遥控器
    var setCommand = function (button, command) {
        button.onclick = function () {
            command.execute()
        }
    }
    // 请求者
    var MenuBar = {
        refresh:function () {
            console.log('刷新菜单目录')
        }
    }

    var SubMenu = {
        add:function () {
            console.log('增加子菜单')
        },
        del:function () {
            console.log('删除子菜单')
        }
    }
    // ---------------命令(命令的参数是要执行请求者)-------------------
    // 刷新菜单
    var RefreshMenuBarCommand = function (receiver) {
        this.receiver = receiver
    }
    RefreshMenuBarCommand.prototype.execute = function () {
        this.receiver.refresh()
    }

    // 针对子菜单
    var AddSubMenuCommand = function (receiver) {
        this.receiver = receiver
    }
    AddSubMenuCommand.prototype.execute = function () {
        this.receiver.add()
    }

    var DelSubMenuCommand = function (receiver) {
        this.receiver = receiver
    }
    DelSubMenuCommand.prototype.execute = function () {
        console.log('删除子菜单')
    }
    // 指定命令的请求者
    var refreshMenuBarCommand = new RefreshMenuBarCommand( MenuBar );
    var addSubMenuCommand = new AddSubMenuCommand( SubMenu );
    var delSubMenuCommand = new DelSubMenuCommand( SubMenu );
    
    // 执行
    setCommand( button1, refreshMenuBarCommand );
    setCommand( button2, addSubMenuCommand );
    setCommand( button3, delSubMenuCommand );
</script>

</html>
  • 结果分析
1.现在画按钮的A同学画完了按钮,写完了'Invoker' -- 'setCommand' 也就是请求调用者这个方法,
他不用知道这些按钮具体方法实现,也不用知道具体代码实现
2.B同学写完了方法,也将指令的类封装好了,现在他要做的就是调用一下,A同学封装的'Invoker'

总结

1.书中举了一个订餐的例子,我们现在来看这个例子,结合代码分析这个理解,一个人去点餐,服务员
是一个调用者,点餐的不用知道那个厨师给我做的饭,只需要告诉调用者,调用者将这个指令告诉
对应的厨师即可

热门文章

暂无图片
编程学习 ·

解决VBE6EXT.OLB不能被加载问题

一般出现这个问题的话,就是配置有问题了,或者是你的VBE6EXT.OLB文件出了问题,看了网上一堆方法,试了很多都不管用,然后综合了一下,总结出了不能用的原因和解决方法:第一种方法: 将自己电脑内的VBA文件转移一下: 路径是由 C:\Program Files (x86)\Common Files\microso…
暂无图片
编程学习 ·

Unity的学习(二):打砖块

一、新建项目创建成功后,进入了如下界面。二、场景的设计 在Hierarchy中鼠标右键创建Plane(地面)游戏物体,将其Transform组件重置,并将游戏物体重命名为Ground,如下图所示。调整地面的大小。在Assets下创建文件夹Materials,并在其中创建Ground的Material(材质)并在Gro…
暂无图片
编程学习 ·

Linux安全原理简介

Linux安全原理简介介绍在设置Linux计算机的所有阶段,安全性应是首要考虑之一。要在计算机上实施良好的安全策略,需要对Linux的基础知识以及所使用的某些应用程序和协议有充分的了解。Linux的安全性是一个非常重要的主题,并且有许多有关此主题的完整书籍。我不能在本教程中介…
暂无图片
编程学习 ·

leetcode 718.最长重复子数组

原题 718.最长重复子数组 2020年7月1日 每日一题题解 方法一 暴力法。 /*暴力法 @v7fgg 执行用时:2265 ms, 在所有 Java 提交中击败了5.00%的用户 内存消耗:39.3 MB, 在所有 Java 提交中击败了100.00%的用户 2020年7月1日 8:03 */ class Solution {public int findLength(int…
暂无图片
编程学习 ·

Hadoop----HDFS的API操作

HDFS文件上传 1、源代码` @Test public void testCopyFromLocalFile() throws IOException,InterruptedException,URISyntaxException{//1、获取文件系统Configuration configuration = new Configuration();configuration.set("dfs.replication","2");//副…
暂无图片
编程学习 ·

APP免费渠道,运营者不可不知的基础常识

​随着移动终端的迅速普及,各类APP如雨后春笋般涌现出来,但是真正的运营成功的产品却寥寥无几。从瓜分渠道资源到抢占用户的过程中,很多同行都明显的感觉到,渠道平台所带来的量日益减少,但是刊例价格却一再攀升。就像圈内的朋友和我在聊天的提到的:“现在渠道的大腿真心越…
暂无图片
编程学习 ·

小程序学习之路五:scroll-view实现多列布局

上面讲解了一些部分简单功能,接下来讲讲scroll-view的进阶,实现多列布局,先上效果:首先来看看布局文件<scroll-view class="scroll"><view class="item" wx:for={{datas}} wx:key=index wx:for-item="item" data-item="{{item…
暂无图片
编程学习 ·

FPGA之fifo设计

FPGA之手撕fifo(含设计代码和仿真)本文回答以下几个问题:1:fifo的读空和写满信号如何给出2:fifo的写控制模块设计3:fifo的读控制模块设计4:双口RAM使用5:顶层文件6:仿真文件编写7:modelsim的RTL仿真1:上一篇文章(FPGA之FIFO IP核详细教程)已经简单说了一下读写指针…
暂无图片
编程学习 ·

献给mac新手,Mac日常软件APP推荐

不少初入Mac 或者 Macbook 的朋友会因为 macOS 系统的独特性而感到新奇又迷惑,它不仅在操作逻辑上和 Windows 大相径庭,软件生态也是截然不同。初用 macOS 系统时可能会一头雾水,完全不知道自己应该去哪里下载 App,也不知道有哪些常用的 App。其实 Mac 上有很多精致又好用的…
暂无图片
编程学习 ·

FFmpeg快速压缩,短视频秒播,视频流m3u8生成

FFMpeg快速压缩test.mp4是视频地址 libx264表示视频编码格式为H.264 crf 表示控制转码,18-28比较合理,18表示无损压缩,28表示有损的压缩,28压缩出来的视频会模糊 test_compressed.mp4表示压缩后的视频路径ffmpeg -i test.mp4 -vcodec libx264 -crf 22 -preset veryfast -c:…
暂无图片
编程学习 ·

浅析为什么开发中阿里禁用Select *查询

1、低效率原因 首先看下阿里开发手册中关于Mysql的描述: 4 - 1. 【强制】在表查询中,一律不要使用 * 作为查询的字段列表,需要哪些字段必须明确写明。 说明: 增加查询分析器解析成本。 增减字段容易与 resultMap 配置不一致。 无用字段增加网络 消耗,尤其是 text 类型的字…
暂无图片
编程学习 ·

一文聊透This

Thisthis指向当前属性所在对象。 var A = {name: 张三,describe: function () {return 姓名:+ this.name;} };var name = 李四; var f = A.describe; f() // "姓名:李四"JavaScript 语言之中,一切皆对象,运行环境也是对象,所以函数都是在某个对象之中运行,this…
暂无图片
编程学习 ·

字符串专题之 leetcode 537. 复数乘法

题目: 给定两个表示复数的字符串。 返回表示它们乘积的字符串。注意,根据定义 i2 = -1 。 示例 1: 输入: “1+1i”, “1+1i” 输出: “0+2i” 解释: (1 + i) * (1 + i) = 1 + i2 + 2 * i = 2i ,你需要将它转换为 0+2i 的形式。 示例 2: 输入: “11i”, “11i” 输出: “02i”…
暂无图片
编程学习 ·

jvm垃圾收集算法以垃圾收集器简介

jvm垃圾收集算法以垃圾收集器简介 每天多学一点点~ 话不多说,这就开始吧… 文章目录jvm垃圾收集算法以垃圾收集器简介1.前言2.内存模型判断机制3.垃圾收集算法3.1 分代收集理论3.2 标记-复制算法3.3 标记-清除算法3.4 标记-整理算法4.常用的垃圾收集器4.1 Serial收集器(-XX:+U…
暂无图片
编程学习 ·

jvm垃圾收集器你学废了吗(二)

前言 前面一篇文章讲了6种垃圾收集器分别是Serial、ParNew、Parallel Scavenge、Serial Old、Parallel Old、CMS(传送门) 今天我们来说一下G1(Garbage First)收集器,为什么把G1收集器单独拿出来说呢?它是垃圾收集器技术发展历史上的里程碑式的成果,下面我们细细道来G1收…
暂无图片
编程学习 ·

谷粒商城-elasticsearch

1. elasticsearch基本操作 1.1. 基本概念 Elasticsearch也是基于Lucene的全文检索库,本质也是存储数据,很多概念与MySQL类似的。 对比关系: 索引(indices)----------------------Databases 数据库类型(type)--------------------------Table 数据表文档(Document)--…
暂无图片
编程学习 ·

视频项目的“云、边、端”公式

视频项目各种各样,视频方案也是千变万化,可以有多种形式的组合来解决问题,最终选择具体哪一种方案可能会根据成本、效果、可行性等多个方面来综合,那么,有没有一套公式可以解决视频项目的需求? 可以说是有的,我总结了一套视频“云、边、端”的公式,可以在具体项目实践中…
暂无图片
编程学习 ·

操作系统复习概要

题型:选择题 11题*2分 基本概念以及数据结构 名词解释 5题*3分 解答题 5题*5分 问答与计算题 12 13 13 分5 6 9 11非标准试题1了解:计算机系统的状态——CPU用户态,系统态,状态、概念以及引入原因用户态:一些内存区域受到保护;特权指令不能执行 系统态:受保护的内存区域…