JavaScript设计模式之命令模式实例分析


Posted in Javascript onJanuary 16, 2019

本文实例讲述了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

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

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

Javascript 相关文章推荐
jquery选择器之基本过滤选择器详解
Jan 27 Javascript
JQuery报错Uncaught TypeError: Illegal invocation的处理方法
Mar 13 Javascript
JavaScript正则表达式之multiline属性的应用
Jun 16 Javascript
使用JS轻松实现ionic调用键盘搜索功能(超实用)
Sep 06 Javascript
关于 jQuery Easyui异步加载tree的问题解析
Dec 06 Javascript
微信小程序 扎金花简单实例
Feb 21 Javascript
js绑定事件和解绑事件
Apr 27 Javascript
JS将unicode码转中文方法
May 08 Javascript
Vue.js 中取得后台原生HTML字符串 原样显示问题的解决方法
Jun 10 Javascript
el-input 标签中密码的显示和隐藏功能的实例代码
Jul 19 Javascript
node删除、复制文件或文件夹示例代码
Aug 13 Javascript
ES6如何用一句代码实现函数的柯里化
Jan 18 Javascript
js删除数组中某几项的方法总结
Jan 16 #Javascript
JavaScript设计模式之责任链模式实例分析
Jan 16 #Javascript
JavaScript设计模式之代理模式实例分析
Jan 16 #Javascript
vue-cli中vue本地实现跨域调试接口
Jan 16 #Javascript
vue element动态渲染、移除表单并添加验证的实现
Jan 16 #Javascript
深入koa-bodyparser原理解析
Jan 16 #Javascript
jQuery实现的点击图片居中放大缩小功能示例
Jan 16 #jQuery
You might like
长波知识介绍
2021/03/01 无线电
正则表达式语法
2006/10/09 Javascript
Win2000+Apache+MySql+PHP4+PERL安装使用小结
2006/10/09 PHP
php中将时间差转换为字符串提示的实现代码
2011/08/08 PHP
php 无法加载mcrypt.dll的解决办法
2013/04/03 PHP
php获取客户端IP及URL的方法示例
2017/02/03 PHP
符合标准的js表单提交的代码
2007/09/13 Javascript
extjs 的权限问题 要求控制的对象是 菜单,按钮,URL
2010/03/09 Javascript
js使用eval解析json(js中使用json)
2014/01/17 Javascript
javascript设计模式之解释器模式详解
2014/06/05 Javascript
Egret引擎开发指南之发布项目
2014/09/03 Javascript
javascript表格隔行变色加鼠标移入移出及点击效果的方法
2015/04/10 Javascript
JS onkeypress兼容性写法详解
2016/04/27 Javascript
cocos creator Touch事件应用(触控选择多个子节点的实例)
2017/09/10 Javascript
JS获取日期的方法实例【昨天,今天,明天,前n天,后n天的日期】
2017/09/28 Javascript
原生JavaScript实现todolist功能
2018/03/02 Javascript
jQuery中元素选择器(element)简单用法示例
2018/05/14 jQuery
详解使用create-react-app添加css modules、sasss和antd
2018/07/31 Javascript
微信小程序swiper实现滑动放大缩小效果
2018/11/15 Javascript
layUI实现三级导航菜单效果
2019/07/26 Javascript
python实现提取百度搜索结果的方法
2015/05/19 Python
Python开发最牛逼的IDE——pycharm
2018/08/01 Python
python将秒数转化为时间格式的实例
2018/09/16 Python
django将数组传递给前台模板的方法
2019/08/06 Python
如何基于windows实现python定时爬虫
2020/05/01 Python
利用python为PostgreSQL的表自动添加分区
2021/01/18 Python
如何避免常见的6种HTML5错误用法
2017/11/06 HTML / CSS
世界上最大的折扣香水店:FragranceNet.com
2016/10/26 全球购物
专注澳大利亚特产和新西兰特产的澳洲中文网:0061澳洲制造
2019/03/24 全球购物
《莫泊桑拜师》教学反思
2014/04/23 职场文书
承诺书样本
2014/08/30 职场文书
2015年五四青年节演讲稿
2015/03/18 职场文书
2016年大学迎新工作总结
2015/10/14 职场文书
传单、海报早OUT了,另类传单营销方案送给你!
2019/07/15 职场文书
Java图书管理系统,课程设计必用(源码+文档)
2021/06/30 Java/Android
Spring Cloud Gateway去掉url前缀
2021/07/15 Java/Android