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 相关文章推荐
第一个JavaScript入门基础 document.write输出
Feb 22 Javascript
js鼠标及对象坐标控制属性详细解析
Dec 14 Javascript
JS中使用apply方法通过不同数量的参数调用函数的方法
May 31 Javascript
原生js实现弹出层效果
Jan 20 Javascript
Node.js v8.0.0正式发布!看看带来了哪些主要新特性
Jun 02 Javascript
基于webpack 实用配置方法总结
Sep 28 Javascript
JQuery元素快速查找与操作
Apr 22 jQuery
对angular4子路由&amp;辅助路由详解
Oct 09 Javascript
Vue 前端实现登陆拦截及axios 拦截器的使用
Jul 17 Javascript
vuex的数据渲染与修改浅析
Nov 26 Vue.js
JavaScript的一些小技巧分享
Jan 06 Javascript
使用vue-element-admin框架从后端动态获取菜单功能的实现
Apr 29 Vue.js
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
利用中国天气预报接口实现简单天气预报
2014/01/20 PHP
ThinkPHP中自定义错误页面和提示页面实例
2014/11/22 PHP
PHP基于工厂模式实现的计算器实例
2015/07/16 PHP
学习php设计模式 php实现享元模式(flyweight)
2015/12/07 PHP
PHP用PDO如何封装简单易用的DB类详解
2017/07/30 PHP
jQuery AJAX实现调用页面后台方法和web服务定义的方法分享
2012/03/01 Javascript
jquery子元素过滤选择器使用示例
2013/06/24 Javascript
jQuery事件之键盘事件(ctrl+Enter回车键提交表单等)
2014/05/11 Javascript
基于zepto.js实现仿手机QQ空间的大图查看组件ImageView.js详解
2015/03/05 Javascript
移除AngularJS下URL中的#字符的方法
2015/06/19 Javascript
JavaScript SHA512&amp;SHA256加密算法详解
2015/08/11 Javascript
浅谈javascript中的call、apply、bind
2016/03/06 Javascript
浅析Javascript ES6中的原生Promise
2016/08/25 Javascript
JS多文件上传的实例代码
2017/01/11 Javascript
layDate日期控件使用方法详解
2018/11/15 Javascript
关于layui 实现点击按钮添加一行(方法渲染创建的table)
2019/09/29 Javascript
微信小程序实现同时上传多张图片
2020/02/03 Javascript
pyqt 多窗口之间的相互调用方法
2019/06/19 Python
Python的几种主动结束程序方式
2019/11/22 Python
浅谈cv2.imread()和keras.preprocessing中的image.load_img()区别
2020/06/12 Python
Pandas对DataFrame单列/多列进行运算(map, apply, transform, agg)
2020/06/14 Python
python开发入门——列表生成式
2020/09/03 Python
python 三种方法提取pdf中的图片
2021/02/07 Python
CSS3的RGBA中关于整数和百分比值的转换
2015/08/04 HTML / CSS
美国顶级户外凉鞋品牌:Chacos
2017/03/27 全球购物
印度在线内衣和时尚目的地:Zivame
2017/09/28 全球购物
英国绿色商店:Natural Collection
2019/05/03 全球购物
求职自荐信范文格式
2013/11/29 职场文书
三爱活动实施方案
2014/03/19 职场文书
环保倡议书怎么写
2014/05/16 职场文书
医德医魂心得体会
2014/09/11 职场文书
2016年寒假社会实践活动总结
2015/03/27 职场文书
民主生活会主持词
2015/07/01 职场文书
面试必问:圣杯布局和双飞翼布局的区别
2021/05/13 HTML / CSS
python中的plt.cm.Paired用法说明
2021/05/31 Python
MySQL生成千万测试数据以及遇到的问题
2022/08/05 MySQL