JavaScript命令模式原理与用法实例详解


Posted in Javascript onMarch 10, 2020

本文实例讲述了JavaScript命令模式原理与用法。分享给大家供大家参考,具体如下:

第一,命令模式:
(1)用于消除调用者和接收者之间直接的耦合的模式,并且可以对(调用这个过程进行留痕操作)

(2)真的不要乱用这个模式,以为他使你简单调用写法变得非常的复杂和有些难以理解。

(3)你的业务出现了 (回退操作)(重做操作)的需求的时候你就要考虑使用这个模式了。
命令的原理:
JavaScript命令模式原理与用法实例详解

一种情况为发出者直接作用于执行者,这样耦合度很高,另外一种情况为,在发出者和执行者之间增加一个用存储命令的命令访问库也即命令命令模式。

第二,现在我们通过一个需求来学习该模式
需求为:

1.有一个"添加流程的按钮"单击的时候 就会添加一个新的文本当做流程的描述

2.有"返回","重做" 2个按钮来完成相应的任务。
第三,界面为

<body>
<input type="text" id="flow">
<input type="button" value="添加新流程" onclick="API.addFlow()">
<br>
<input type="button" value="ctrl+z回退" onclick="API.ret()">
<input type="button" value="ctrl+z+x重做" onclick="API.again()">
<div id= "div01"></div>

<script src="Js/设计模式第三部分/命令模式/keymaster.min.js"></script>
<script src="Js/设计模式第三部分/命令模式/uuid.js"></script>
<script src="Js/设计模式第三部分/命令模式/(18)命令模式.js"></script>
</body>

  效果为,JavaScript命令模式原理与用法实例详解

根据上述图我们逐步完成
步骤一,定义主应用程序----接收者

function manager() {
        this.addFlow=function (id,value) {
            //1.得到目标节点
          var div=document.getElementById("div01");
          var newFlow=document.createElement("div");
          newFlow.setAttribute("id",id);
          newFlow.innerHTML=value;
          div.appendChild(newFlow);

        }
    }

 步骤二,为对象(执行者)建立命令访问库 ---意思是可以通过extcute方法访问到addFlow方法

manager.prototype.extcute=(function () {
      /*command 命令对象
      * */
      return function (command) {
        return this[command.method](command.id,command.value);
      }

    })();

步骤三,初始化主类

var ma = new manager();//可以用该对象,调用其的东西
      //用于存储"调用对象命令的"集合
      var commands = new Array();
      //集合的游标--初始化在末尾
      var index = commands.length;

步骤四,客户端----发出者

var API=function () {
   this.addFlow=function () {
     //把调用封装起来
     var command={
       method:"addFlow",
       id:new UUID().createUUID(),//产生id的插件
       value:document.getElementById("flow").value
     };
     //把调用对象保存起来,用于回退和重做作用
     commands.push(command);
     //重新定位游标---赋值记录
     index = commands.length;
     //调用
     ma.extcute(command);
   };
   /**
    * 用于返回的方法
    */
   this.ret=function () {
     if(index-1<0){
       alert("已经到了最后一步了...");
     }else {
       var all=document.getElementById("div01").childNodes;
       document.getElementById("div01").removeChild(all[all.length-1]);
       index=index-1;
     }
   };
   /**
    * 用于重做的方法
    */
   this.again=function () {
     if(index>=commands.length){
       alert("已经到了最前面一步了,不能进行重做...");
     }else {
       var command=commands[index];//获取当前的命令位置
       ma.extcute(command);
       index=index+1;
     }
   }
 }

步骤五,实例化客户端

API=new API();//实例化

这样html中的事件就可以起作用了。

在这里我们使用插件来让其功能支持自定义的键盘事件,插件名称为:keymaster.js

首先,如html中一样引入文件,

然后值调用key添加自定义的键盘事件

//添加支持ctrl+z--返回
key("ctrl+z",function () {

  API.ret();
});
//重做---
key("ctrl+shift+x",function () {
  API.again();

})

为此我们可以使用键盘的指定组合实现和鼠标点击一样的效果。

这里需要说明一下客户端的API中的id值,也是通过插件来动态生成的------插件名称为:uuid.js。这里附上源码

/*

uuid.js - Version 0.2
JavaScript Class to create a UUID like identifier

Copyright (C) 2006-2008, Erik Giberti (AF-Design), All rights reserved.

This program is free software; you can redistribute it and/or modify it under 
the terms of the GNU General Public License as published by the Free Software 
Foundation; either version 2 of the License, or (at your option) any later 
version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY 
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with 
this program; if not, write to the Free Software Foundation, Inc., 59 Temple 
Place, Suite 330, Boston, MA 02111-1307 USA

The latest version of this file can be downloaded from
http://www.af-design.com/resources/javascript_uuid.php

HISTORY:
6/5/06   - Initial Release
5/22/08 - Updated code to run faster, removed randrange(min,max) in favor of
     a simpler rand(max) function. Reduced overhead by using getTime() 
     method of date class (suggestion by James Hall).

KNOWN ISSUES:
- Still no way to get MAC address in JavaScript
- Research into other versions of UUID show promising possibilities 
 (more research needed)
- Documentation needs improvement

*/

// On creation of a UUID object, set it's initial value
function UUID(){
  this.id = this.createUUID();
}

// When asked what this Object is, lie and return it's value
UUID.prototype.valueOf = function(){ return this.id; }
UUID.prototype.toString = function(){ return this.id; }

//
// INSTANCE SPECIFIC METHODS
//

UUID.prototype.createUUID = function(){
  //
  // Loose interpretation of the specification DCE 1.1: Remote Procedure Call
  // described at http://www.opengroup.org/onlinepubs/009629399/apdxa.htm#tagtcjh_37
  // since JavaScript doesn't allow access to internal systems, the last 48 bits 
  // of the node section is made up using a series of random numbers (6 octets long).
  // 
  var dg = new Date(1582, 10, 15, 0, 0, 0, 0);
  var dc = new Date();
  var t = dc.getTime() - dg.getTime();
  var h = '-';
  var tl = UUID.getIntegerBits(t,0,31);
  var tm = UUID.getIntegerBits(t,32,47);
  var thv = UUID.getIntegerBits(t,48,59) + '1'; // version 1, security version is 2
  var csar = UUID.getIntegerBits(UUID.rand(4095),0,7);
  var csl = UUID.getIntegerBits(UUID.rand(4095),0,7);

  // since detection of anything about the machine/browser is far to buggy, 
  // include some more random numbers here
  // if NIC or an IP can be obtained reliably, that should be put in
  // here instead.
  var n = UUID.getIntegerBits(UUID.rand(8191),0,7) + 
      UUID.getIntegerBits(UUID.rand(8191),8,15) + 
      UUID.getIntegerBits(UUID.rand(8191),0,7) + 
      UUID.getIntegerBits(UUID.rand(8191),8,15) + 
      UUID.getIntegerBits(UUID.rand(8191),0,15); // this last number is two octets long
  return tl + h + tm + h + thv + h + csar + csl + h + n; 
}


//
// GENERAL METHODS (Not instance specific)
//


// Pull out only certain bits from a very large integer, used to get the time
// code information for the first part of a UUID. Will return zero's if there 
// aren't enough bits to shift where it needs to.
UUID.getIntegerBits = function(val,start,end){
  var base16 = UUID.returnBase(val,16);
  var quadArray = new Array();
  var quadString = '';
  var i = 0;
  for(i=0;i<base16.length;i++){
    quadArray.push(base16.substring(i,i+1));  
  }
  for(i=Math.floor(start/4);i<=Math.floor(end/4);i++){
    if(!quadArray[i] || quadArray[i] == '') quadString += '0';
    else quadString += quadArray[i];
  }
  return quadString;
}

// Numeric Base Conversion algorithm from irt.org
// In base 16: 0=0, 5=5, 10=A, 15=F
UUID.returnBase = function(number, base){
  //
  // Copyright 1996-2006 irt.org, All Rights Reserved.  
  //
  // Downloaded from: http://www.irt.org/script/146.htm  
  // modified to work in this class by Erik Giberti
  var convert = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
  if (number < base) var output = convert[number];
  else {
    var MSD = '' + Math.floor(number / base);
    var LSD = number - MSD*base;
    if (MSD >= base) var output = this.returnBase(MSD,base) + convert[LSD];
    else var output = convert[MSD] + convert[LSD];
  }
  return output;
}

// pick a random number within a range of numbers
// int b rand(int a); where 0 <= b <= a
UUID.rand = function(max){
  return Math.floor(Math.random() * max);
}

// end of UUID class file

感兴趣的朋友可以使用在线HTML/CSS/JavaScript前端代码调试运行工具:http://tools.3water.com/code/WebCodeRun测试上述代码运行效果。

更多关于JavaScript相关内容还可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
学习jquery之一
Apr 27 Javascript
jQuery对象和DOM对象相互转化
Apr 24 Javascript
推荐一个封装好的getElementsByClassName方法
Dec 02 Javascript
JavaScript实现常用二级省市级联下拉列表的方法
Mar 25 Javascript
javascript 判断两个日期之差的示例代码
Sep 05 Javascript
Vuejs第十篇之vuejs父子组件通信
Sep 06 Javascript
鼠标经过出现气泡框的简单实例
Mar 17 Javascript
详谈js遍历集合(Array,Map,Set)
Apr 06 Javascript
JS实现的JSON序列化操作简单示例
Jul 02 Javascript
详解webpack打包后如何调试的方法步骤
Nov 07 Javascript
如何让微信小程序页面之间的通信不再变困难
Jun 03 Javascript
微信小程序通过js实现瀑布流布局详解
Aug 28 Javascript
JavaScript实现指定数量的并发限制的示例代码
Mar 10 #Javascript
vue中的使用token的方法示例
Mar 10 #Javascript
vue瀑布流组件实现上拉加载更多
Mar 10 #Javascript
JS如何在数组指定位置插入元素
Mar 10 #Javascript
vue实现简单瀑布流布局
May 28 #Javascript
JavaScript观察者模式原理与用法实例详解
Mar 10 #Javascript
微信小程序用canvas画图并分享
Mar 09 #Javascript
You might like
php判断正常访问和外部访问的示例
2014/02/10 PHP
PHP类型约束用法示例
2016/09/28 PHP
基于json的jquery地区联动效果代码
2011/07/06 Javascript
Javascript this 的一些学习总结
2012/08/31 Javascript
Angular用来控制元素的展示与否的原生指令介绍
2015/01/07 Javascript
基于javascript实现九宫格大转盘效果
2020/05/28 Javascript
Javascript点击按钮随机改变数字与其颜色
2016/09/01 Javascript
vue eslint简要配置教程详解
2019/07/26 Javascript
js实现左右轮播图
2020/01/09 Javascript
JS寄快递地址智能解析的实现代码
2020/07/16 Javascript
vue中使用echarts的示例
2021/01/03 Vue.js
[01:35]辉夜杯战队访谈宣传片—iG.V
2015/12/25 DOTA
Python中dictionary items()系列函数的用法实例
2014/08/21 Python
实例讲解Python设计模式编程之工厂方法模式的使用
2016/03/02 Python
Python的collections模块中的OrderedDict有序字典
2016/07/07 Python
使用tensorflow实现AlexNet
2017/11/20 Python
Python获取指定文件夹下的文件名的方法
2018/02/06 Python
python提取具有某种特定字符串的行数据方法
2018/12/11 Python
Python学习笔记之错误和异常及访问错误消息详解
2019/08/08 Python
Django Path转换器自定义及正则代码实例
2020/05/29 Python
Python如何把字典写入到CSV文件的方法示例
2020/08/23 Python
python自动化测试三部曲之request+django实现接口测试
2020/10/07 Python
Python 调用 ES、Solr、Phoenix的示例代码
2020/11/23 Python
python+selenium自动化实战携带cookies模拟登陆微博
2021/01/19 Python
python实现计算图形面积
2021/02/22 Python
Python绘制K线图之可视化神器pyecharts的使用
2021/03/02 Python
css3针对移动端卡顿问题的解决(动画性能优化)
2020/02/14 HTML / CSS
AmazeUI 点击元素显示全屏的实现
2020/08/25 HTML / CSS
英格兰橄榄球商店:England Rugby Store
2016/12/17 全球购物
大学生旷课检讨书
2014/01/22 职场文书
电子商务专业学生职业生涯规划
2014/03/07 职场文书
我的中国梦演讲稿600字
2014/08/19 职场文书
服务员态度差检讨书
2014/10/28 职场文书
留学推荐信(中英文版)
2015/03/26 职场文书
大学升旗仪式主持词
2015/07/04 职场文书
vue-treeselect的基本用法以及解决点击无法出现拉下菜单
2022/04/30 Vue.js