<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>javascript高级语法21-命令模式</title>
</head>
<body>
<input type="text" id="flow" />
<input type="button" id="" value="添加新流程" onclick="API.addFlow()" /><br>
<input type="button" value="回退" onclick="API.re()" />
<input type="button" value="重做" onclick="API.again()" />
<div id="div01"></div> <script id="uuid.js">
//生成uuid的轮子
/*
uuid.js - Version 0.2
JavaScript Class to create a UUID like identifier
*/ // 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; }
UUID.prototype.createUUID = function(){
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);
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;
} 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;
} UUID.returnBase = function(number, base){ 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;
}
UUID.rand = function(max){
return Math.floor(Math.random() * max);
} </script>
<script id="keymaster.js">
//获取键盘事件的轮子
(function(a) {
function h(a, b) {
var c = a.length;
while (c--) if (a[c] === b) return c;
return -1
}
function i(a) {
var b, g, i, j, k;
b = a.keyCode;
if (b == 93 || b == 224) b = 91;
if (b in d) {
d[b] = !0;
for (i in f) f[i] == b && (l[i] = !0);
return
}
if (!l.filter.call(this, a)) return;
if (!(b in c)) return;
for (j = 0; j < c[b].length; j++) {
g = c[b][j];
if (g.scope == e || g.scope == "all") {
k = g.mods.length > 0;
for (i in d) if (!d[i] && h(g.mods, +i) > -1 || d[i] && h(g.mods, +i) == -1) k = !1;
(g.mods.length == 0 && !d[16] && !d[18] && !d[17] && !d[91] || k) && g.method(a, g) === !1 && (a.preventDefault ? a.preventDefault() : a.returnValue = !1, a.stopPropagation && a.stopPropagation(), a.cancelBubble && (a.cancelBubble = !0))
}
}
}
function j(a) {
var b = a.keyCode,
c;
if (b == 93 || b == 224) b = 91;
if (b in d) {
d[b] = !1;
for (c in f) f[c] == b && (l[c] = !1)
}
}
function k() {
for (b in d) d[b] = !1;
for (b in f) l[b] = !1
}
function l(a, b, d) {
var e, h, i, j;
d === undefined && (d = b, b = "all"), a = a.replace(/\s/g, ""), e = a.split(","), e[e.length - 1] == "" && (e[e.length - 2] += ",");
for (i = 0; i < e.length; i++) {
h = [], a = e[i].split("+");
if (a.length > 1) {
h = a.slice(0, a.length - 1);
for (j = 0; j < h.length; j++) h[j] = f[h[j]];
a = [a[a.length - 1]]
}
a = a[0], a = g[a] || a.toUpperCase().charCodeAt(0), a in c || (c[a] = []), c[a].push({
shortcut: e[i],
scope: b,
method: d,
key: e[i],
mods: h
})
}
}
function m(a) {
var b = (a.target || a.srcElement).tagName;
return b != "INPUT" && b != "SELECT" && b != "TEXTAREA"
}
function n(a) {
e = a || "all"
}
function o() {
return e || "all"
}
function p(a) {
var b, d, e;
for (b in c) {
d = c[b];
for (e = 0; e < d.length;) d[e].scope === a ? d.splice(e, 1) : e++
}
}
function q(a, b, c) {
a.addEventListener ? a.addEventListener(b, c, !1) : a.attachEvent && a.attachEvent("on" + b, function() {
c(window.event)
})
}
var b, c = {},
d = {
16: !1,
18: !1,
17: !1,
91: !1
},
e = "all",
f = {
"⇧": 16,
shift: 16,
"⌥": 18,
alt: 18,
option: 18,
"⌃": 17,
ctrl: 17,
control: 17,
"⌘": 91,
command: 91
},
g = {
backspace: 8,
tab: 9,
clear: 12,
enter: 13,
"return": 13,
esc: 27,
escape: 27,
space: 32,
left: 37,
up: 38,
right: 39,
down: 40,
del: 46,
"delete": 46,
home: 36,
end: 35,
pageup: 33,
pagedown: 34,
",": 188,
".": 190,
"/": 191,
"`": 192,
"-": 189,
"=": 187,
";": 186,
"'": 222,
"[": 219,
"]": 221,
"\\": 220
};
for (b = 1; b < 20; b++) f["f" + b] = 111 + b;
for (b in f) l[b] = !1;
q(document, "keydown", i), q(document, "keyup", j), q(window, "focus", k), a.key = l, a.key.setScope = n, a.key.getScope = o, a.key.deleteScope = p, a.key.filter = m, typeof module != "undefined" && (module.exports = key)
})(this);
</script>
<script>
/*命令模式:
* 用于消除调用者和接收者之间的耦合的模式
* 并且可以对(调用这个过程进行留痕操作)
* 不能乱用这个模式,它会使简单调用的写法变得非常复杂和难以理解
* 当你的业务出现了回退操作,重做操作等需求的时候考虑用这个模式
*/
/*需求:
有一个添加流程的按钮,单机的时候添加一个新的文本当做流程的描述
有返回 重做两个按钮,完成相应任务。
*/
function manager(){
this.addFlow = function(id,text){
//1.得到目标节点
var div = document.getElementById("div01");
var newFlow = document.createElement("div");
newFlow.setAttribute("id",id);
newFlow.innerHTML = text;
div.appendChild(newFlow);
}
}
//为对象建立命令访问库
manager.prototype.excute = (function(){
//命令对象
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(),
value:document.getElementById("flow").value,
}
//把调用对象保存起来,用于回退和重做
commands.push(command);
//重新定位游标
index = commands.length;
//调用
ma.excute(command); }
//返回
this.re = function(){
if(index-1<0){
alert("已经到最后一步了!")
}else{
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.excute(command);
index = index + 1;
}
}
}
//实例化api
var API = new API(); //添加支持键盘事件
key("ctrl+z",function(){
API.re();
})
key("ctrl+shift+z",function(){
API.again();
})
</script>
</body>
</html>

JavaScript设计模式-21.命令模式的更多相关文章

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

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

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

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

  3. JavaScript设计模式之命令模式【命令解耦】

    在讲解命令模式之前我们先来了解一个生活中的命令模式场景: 场景1: 医院看病抓药: 当你因为肾虚到医院看医生,医生一番操作之后得出结论:要吃个疗程[夏桑菊].[小柴胡](药名纯属虚构,真的肾虚就找医生 ...

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

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

  5. JavaScript设计模式之----组合模式

    javascript设计模式之组合模式 介绍 组合模式是一种专门为创建Web上的动态用户界面而量身制定的模式.使用这种模式可以用一条命令在多个对象上激发复杂的或递归的行为.这可以简化粘合性代码,使其更 ...

  6. 设计模式 ( 十三 ) 命令模式Command(对象行为型)

    设计模式 ( 十三 ) 命令模式Command(对象行为型) 1.概述         在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需 ...

  7. 乐在其中设计模式(C#) - 命令模式(Command Pattern)

    原文:乐在其中设计模式(C#) - 命令模式(Command Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 命令模式(Command Pattern) 作者:webabcd ...

  8. 面向对象设计模式_命令模式(Command)解读

    在.Net框架中很多对象的方法中都会有Invoke方法,这种方法的设计实际是用了设计模式的命令模式, 模式图如下 其核心思路是将Client 向Receiver发送的命令行为进行抽象(ICommand ...

  9. 折腾Java设计模式之命令模式

    博客原文地址 折腾Java设计模式之命令模式 命令模式 wiki上的描述 Encapsulate a request as an object, thereby allowing for the pa ...

随机推荐

  1. 还原bak到localdb的问题:The logical database file cannot be found ldf

    主要环境相关因素:win7,ms sql 2012,ms localdb,msms 2012. 步骤: 1,让DBA给一个bak文件到本地来做测试,DBA按自己的工作流程得到bak文件. 2,在msm ...

  2. Oracle EBS Add Responsibility to User by the Responsibility reference of Other User.

    Oracle EBS 11i Add Responsibility to User by the Responsibility reference of Other User. Warning: R1 ...

  3. Oracle EBS应用笔记整理 (转自IT++ flyingkite)

    ***************************************************** Author: Flyingkite Blog:   http://space.itpub. ...

  4. 开源WebGIS实施方案(三):Shapefile数据导入到PostGIS

    PostGIS新版中提供了一个可视化的工具,用于Shapefile数据的导入和导出,极大的方便了使用者的操作. 创建空间数据库 以具有创建用户权限的账号登录pgAdminIII,连接到数据库 创建一个 ...

  5. .NET框架源码解读之SSCLI的调试支持

    阅读源码一个比较快的手段就是在调试器里阅读,这样可以在实际运行SSCLI的过程中,通过堆栈跟踪的方式查看完整的程序执行路径. 当在SSCLI环境里执行一个托管程序的时候,堆栈上通常有托管和非托管代码同 ...

  6. 升级windows 10后网络连接异常

    升级 windows 10,QQ无法连接,显示“登陆超时,请检查网络或者防火墙设置”.打开360软件助手,准备升级QQ试试,360软件助手也显示网络异常. 解决方法: 右键点击开始菜单,命令提示符(管 ...

  7. CDH4.1.2 集群安装配置详细过程

    http://wenku.baidu.com/link?url=Wu43MFbzKH8hu7AgGfajmOr0WpRMX_gJlMDUs6pSrBK2LOJWIMpfWZa7IW-BSPko1yGl ...

  8. Linq的Join == 两个foreach

    因为实在太懒了,很久没动笔,今天强迫自己写一个小短篇. 之前讨论过用SelectMany代替两重的foreach循环.今天我们看一下Join和foreach的关系. 首先是Join的定义 public ...

  9. 修改 Cloud image 的密码的简单方法

    下载工具: yum -y install libguestfs-tools.noarch   打开DEBUG: export LIBGUESTFS_DEBUG=1 LIBGUESTFS_TRACE=1 ...

  10. php—Smarty-缓存2(26)

    一个页面中,有些数据缓存,有些数据不缓存,就是局部缓存 l  $smarty->assign(“var”, “value”, true) 第三个参数:表示是否不缓存 l  {$var nocac ...