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 相关文章推荐
JavaScript 继承使用分析
May 12 Javascript
基于jquery可配置循环左右滚动例子
Sep 09 Javascript
js setTimeout opener的用法示例详解
Oct 23 Javascript
jQuery读取和设定KindEditor值的方法
Nov 22 Javascript
js中split函数的使用方法说明
Dec 26 Javascript
plupload+artdialog实现多平台上传文件
Jul 19 Javascript
使用canvas及js简单生成验证码方法
Apr 02 Javascript
详解刷新页面vuex数据不消失和不跳转页面的解决
Jan 30 Javascript
Vue数据双向绑定原理及简单实现方法
May 18 Javascript
一篇文章带你浅入webpack的DLL优化打包
Feb 20 Javascript
es6函数之尾调用优化实例分析
Apr 25 Javascript
jQuery treeview树形结构应用
Mar 24 jQuery
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实现redis数据库指定库号迁移的方法
2015/01/14 PHP
PHP 7的一些引人注目的新特性简单介绍
2015/11/08 PHP
javascript 火狐(firefox)不显示本地图片问题解决
2008/07/05 Javascript
JavaScript 高级篇之闭包、模拟类,继承(五)
2012/04/07 Javascript
Jquery 过滤器(first,last,not,even,odd)的使用
2014/01/22 Javascript
jQuery中siblings()方法用法实例
2015/01/08 Javascript
jQuery仿淘宝网产品品牌隐藏与显示效果
2015/09/01 Javascript
每天一篇javascript学习小结(Function对象)
2015/11/16 Javascript
angularjs 表单密码验证自定义指令实现代码
2016/10/27 Javascript
Bootstrap modal 多弹窗之叠加显示不出弹窗问题的解决方案
2017/02/23 Javascript
jQuery操作之效果详解
2017/05/19 jQuery
关于javascript sort()排序你可能忽略的一点理解
2017/07/18 Javascript
实例讲解Vue.js中router传参
2018/04/22 Javascript
JavaScript数组排序小程序实现解析
2020/01/13 Javascript
[32:17]完美世界DOTA2联赛循环赛LBZS vs Forest第二场 10月30日
2020/10/31 DOTA
python使用reportlab画图示例(含中文汉字)
2013/12/03 Python
Python下载指定页面上图片的方法
2016/05/12 Python
python编程羊车门问题代码示例
2017/10/25 Python
利用Python将文本中的中英文分离方法
2018/10/31 Python
python 常见字符串与函数的用法详解
2018/11/23 Python
Python实现使用request模块下载图片demo示例
2019/05/24 Python
在OpenCV里使用特征匹配和单映射变换的代码详解
2019/10/23 Python
python常用运维脚本实例小结
2020/02/14 Python
django models里数据表插入数据id自增操作
2020/07/15 Python
Html5之svg可缩放矢量图形_动力节点Java学院整理
2017/07/17 HTML / CSS
谈一谈HTML5本地存储技术
2016/03/02 HTML / CSS
职高毕业生自我鉴定
2013/10/21 职场文书
化学学院毕业生自荐信范文
2013/12/17 职场文书
运动会入场词100字
2014/02/06 职场文书
国旗下的讲话演讲稿
2014/05/08 职场文书
党员四风自我剖析材料
2014/10/07 职场文书
签证工作证明模板
2015/06/15 职场文书
勤俭节约主题班会
2015/08/13 职场文书
《清澈的湖水》教学反思
2016/02/17 职场文书
创业计划书之便利店
2019/09/05 职场文书
老生常谈 使用 CSS 实现三角形的技巧(多种方法)
2021/04/13 HTML / CSS