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模拟post提交隐藏地址栏的参数
Sep 03 Javascript
整理Javascript数组学习笔记
Nov 29 Javascript
jquery实现删除一个元素后面的所有元素功能
Dec 21 Javascript
AngularJS入门教程之数据绑定原理详解
Nov 02 Javascript
js实现HashTable(哈希表)的实例分析
Nov 21 Javascript
详解AngularJS中$filter过滤器使用(自定义过滤器)
Feb 04 Javascript
浅谈react前后端同构渲染
Sep 20 Javascript
Angular6中使用Swiper的方法示例
Jul 09 Javascript
jQuery常见的遍历DOM操作详解
Sep 05 jQuery
详解vue中axios请求的封装
Apr 08 Javascript
vue 开发之路由配置方法详解
Dec 02 Javascript
多个Vue项目部署到服务器的步骤记录
Oct 22 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实现递归抓取网页类实例
2015/04/03 PHP
Laravel框架使用monolog_mysql实现将系统日志信息保存到mysql数据库的方法
2018/08/16 PHP
PHP删除数组中指定值的元素常用方法实例分析【4种方法】
2018/08/21 PHP
javascript,jquery闭包概念分析
2010/06/19 Javascript
jquery(hide方法)隐藏指定元素实例
2013/11/11 Javascript
使用AngularJS实现可伸缩的页面切换的方法
2015/06/19 Javascript
javascript中for/in循环及使用技巧
2015/09/01 Javascript
使用jquery+CSS3实现仿windows10开始菜单的下拉导航菜单特效
2015/09/24 Javascript
jquery实现简单实用的弹出层效果代码
2015/10/15 Javascript
jQuery获取元素父节点的方法
2016/06/21 Javascript
jQuery事件委托之Safari
2016/07/05 Javascript
js原生代码实现轮播图的实例讲解
2017/07/28 Javascript
Vue添加请求拦截器及vue-resource 拦截器使用
2017/11/23 Javascript
webpack+vue+express(hot)热启动调试简单配置方法
2018/09/19 Javascript
vue自动路由-单页面项目(非build时构建)
2019/04/30 Javascript
微信小程序自定义modal弹窗组件的方法详解
2020/12/20 Javascript
[02:50]【扭转乾坤,只此一招】DOTA2永雾林渊版本开启新篇章
2020/12/22 DOTA
python中Genarator函数用法分析
2015/04/08 Python
Python双精度浮点数运算并分行显示操作示例
2017/07/21 Python
关于python写入文件自动换行的问题
2018/06/23 Python
python生成密码字典的方法
2018/07/06 Python
Python 十六进制整数与ASCii编码字符串相互转换方法
2018/07/09 Python
python中的字符串内部换行方法
2018/07/19 Python
Python基础之函数基本用法与进阶详解
2020/01/02 Python
如何通过Django使用本地css/js文件
2020/01/20 Python
意大利团购网站:Groupon意大利
2016/10/11 全球购物
全世界最美丽的四星和五星级酒店预订:Prestigia.com
2017/11/15 全球购物
Pureology官网:为染色头发打造最好的产品
2019/09/13 全球购物
经典导游欢迎词大全
2014/01/16 职场文书
酒店总经理助理岗位职责
2014/02/01 职场文书
项目建议书范文
2014/05/12 职场文书
快递员岗位职责
2014/09/12 职场文书
班子查摆四风个人对照检查材料思想汇报
2014/10/04 职场文书
故宫导游词
2015/01/31 职场文书
奖学金申请书(范文)
2019/08/14 职场文书
Java 死锁解决方案
2022/05/11 Java/Android