第一,命令模式: 
(1)用于消除调用者和接收者之间直接的耦合的模式,并且可以对(调用这个过程进行留痕操作)
(2)真的不要乱用这个模式,以为他使你简单调用写法变得非常的复杂和有些难以理解。

(3)你的业务出现了 (回退操作)(重做操作)的需求的时候你就要考虑使用这个模式了。
命令的原理:
一种情况为发出者直接作用于执行者,这样耦合度很高,另外一种情况为,在发出者和执行者之间增加一个用存储命令的命令访问库也即命令命令模式。

第二,现在我们通过一个需求来学习该模式
需求为:
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>

效果为,

根据上述图我们逐步完成
步骤一,定义主应用程序----接收者
 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-<){
alert("已经到了最后一步了...");
}else {
var all=document.getElementById("div01").childNodes;
document.getElementById("div01").removeChild(all[all.length-]);
index=index-;
}
};
/**
* 用于重做的方法
*/
this.again=function () {
if(index>=commands.length){
alert("已经到了最前面一步了,不能进行重做...");
}else {
var command=commands[index];//获取当前的命令位置
ma.extcute(command);
index=index+;
}
}
}

步骤五,实例化客户端

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(, , , , , , );
var dc = new Date();
var t = dc.getTime() - dg.getTime();
var h = '-';
var tl = UUID.getIntegerBits(t,,);
var tm = UUID.getIntegerBits(t,,);
var thv = UUID.getIntegerBits(t,,) + ''; // version 1, security version is 2
var csar = UUID.getIntegerBits(UUID.rand(),,);
var csl = UUID.getIntegerBits(UUID.rand(),,); // 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(),,) +
UUID.getIntegerBits(UUID.rand(),,) +
UUID.getIntegerBits(UUID.rand(),,) +
UUID.getIntegerBits(UUID.rand(),,) +
UUID.getIntegerBits(UUID.rand(),,); // 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,);
var quadArray = new Array();
var quadString = '';
var i = ;
for(i=;i<base16.length;i++){
quadArray.push(base16.substring(i,i+));
}
for(i=Math.floor(start/);i<=Math.floor(end/);i++){
if(!quadArray[i] || quadArray[i] == '') quadString += '';
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 = ['','','','','','','','','','','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命令模式的更多相关文章

  1. javascript设计模式学习之九——命令模式

    一.命令模式使用场景及定义 命令模式常见的使用场景是:有时候需要向某些对象发送请求,但是并不知道请求的接受者是谁,也不知道请求的具体操作是什么.此时希望用一种松耦合的方式来设计程序,使得请求的发送者和 ...

  2. 读书笔记之 - javascript 设计模式 - 命令模式

    本章研究的是一种封装方法调用的方式.命令模式与普通函数有所不同.它可以用来对方法调用进行参数化处理和传送,经过这样处理过的方法调用可以在任何需要的时候执行. 它也可以用来消除调用操作的对象和实现操作的 ...

  3. JavaScript设计模式之命令模式

    一.命令模式概念 命令模式(Command)的定义是:用来对方法调用进行参数化处理和传送,经过这样处理过的方法调用可以在任何需要的时候执行.也就是说该模式旨在将函数的调用.请求和操作封装成一个单一的对 ...

  4. 《JavaScript设计模式与开发实践》读书笔记之命令模式

    1.命令模式 1.1 传统的命令模式 命令模式的应用场景:请求的发送者和请求接收者消除彼此耦合关系 以页面点击按钮为例 点击按钮后,借助命令对象,解开按钮和负责具体行为对象之间的耦合 <body ...

  5. javascript设计模式详解之命令模式

    每种设计模式的出现都是为了弥补语言在某方面的不足,解决特定环境下的问题.思想是相通的.只不过不同的设计语言有其特定的实现.对javascript这种动态语言来说,弱类型的特性,与生俱来的多态性,导致某 ...

  6. 再起航,我的学习笔记之JavaScript设计模式21(命令模式)

    命令模式 概念描述 命令模式(Command): 将请求与实现解耦并封装成独立的对象,从而使不同的请求对客户端的实现参数化 示例代码 命令模式我们可以看成是将创建模块的逻辑封装在一个对象里,这个对象提 ...

  7. javascript设计模式——命令模式

    前面的话 假设有一个快餐店,而我是该餐厅的点餐服务员,那么我一天的工作应该是这样的:当某位客人点餐或者打来订餐电话后,我会把他的需求都写在清单上,然后交给厨房,客人不用关心是哪些厨师帮他炒菜.餐厅还可 ...

  8. JavaScript 设计模式之命令模式

    一.命令模式概念解读 1.命令模式概念文字解读 命令模式(Command)的定义是:用来对方法调用进行参数化处理和传送,经过这样处理过的方法调用可以在任何需要的时候执行.也就是说该模式旨在将函数的调用 ...

  9. JavaScript设计模式-21.命令模式

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

随机推荐

  1. 201521123071 《JAVA程序设计》第四周学习总结

    1. 本周学习总结 1.1 1.2 在本周的学习中,主要学习了以下几点: 注释的应用,并能在Eclipse中查看 继承的基本定义,关键字super的用法,覆盖与重载 多态与is-a,instanceo ...

  2. Android中显示和隐式Intent的使用

    显示启动activity                                                                                         ...

  3. 201521123059 《Java程序设计》第十二周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2. 书面作业 将Student对象(属性:int id, String name,int age,doubl ...

  4. 201521123022 《Java程序设计》 第九周学习总结

    1.本章学习总结 2. 书面作业 本次PTA作业题集异常 1.常用异常 题目5-1 Q1.1 截图你的提交结果(出现学号) Q1.2 自己以前编写的代码中经常出现什么异常.需要捕获吗(为什么)?应如何 ...

  5. 201521123044 《Java程序设计》第1周学习总结

    *** 1.本章学习总结 你对于本章知识的学习总结 1.了解了Java的发展史. 2.学习了什么是JVM,区分JRE与JDK,下载JDK. 3.从C语言的.c 到C++的 .cpp再到Java的.ja ...

  6. 关于SVM数学细节逻辑的个人理解(三) :SMO算法理解

    第三部分:SMO算法的个人理解 接下来的这部分我觉得是最难理解的?而且计算也是最难得,就是SMO算法. SMO算法就是帮助我们求解: s.t.   这个优化问题的. 虽然这个优化问题只剩下了α这一个变 ...

  7. .Net45下HttpClient的几个缺陷

    前言 最近在写WebClientApi这个组件,底层使用HttpClient,发现HttpClient有许多低级的错误,使用者一不小心就可能会正常的去调用它的这些错误,得不到预期的结果.本文我把我认为 ...

  8. 如何在CentOS上安装一个2048小游戏

    如何在centos上安装一个2048小游戏 最近在学习CentOS系统,就琢磨着玩点什么,然后我看到有人在玩2048小游戏,所有我就在想,为啥不装一个2048小游戏搞一下嘞,于是乎,我就开始工作啦 由 ...

  9. GCD之Apply

    dispatch_apply函数是dispatch_sync函数和dispatch_group的结合体.该函数将按指定的次数将指定的block追加到指定的dispatch queue中,并等待全部处理 ...

  10. 多年iOS开发经验总结

    总结了几个月的东西终于能和大家分享了,不多说,直接看东西! 1.禁止手机睡眠 1 [UIApplication sharedApplication].idleTimerDisabled = YES; ...