<!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. SqlLocalDB 的一些常用命令行

    Once installed, you can interact with SqlLocalDb using the command line. The following will tell you ...

  2. HDU 5974 A Simple Math Problem(数论+结论)

    Problem Description Given two positive integers a and b,find suitable X and Y to meet the conditions ...

  3. eclipse中配置server中选择tomcat8无法进行下一步处理

    在创建server的时候,选择tomcat8后,server name为空,并且无法手动输入,同时无法进行下一步操作. 解决方案如下: 1.退出eclipse. 2.找到eclipse[工作空间][当 ...

  4. IIS部署网站常见问题

    有时候Web项目在VS开发环境下没有问题,但是在IIS服务器下却出现了问题. 这让人很抓狂. 在这里总结下通常发生这种问题的几个主要原因. 1.IIS注册.Net框架. 1.1:C:\WINDOWS\ ...

  5. SQL Server—— 如何创建定时作业

    在做SQL server 管理时,往往需要每日执行定时任务,但是如果每天都去人工执行,非常不方便,而且一般定时操作,都应该是在数据库压力不大时,一般是在夜间.所以我们需要创建定时作业来代替人工的执行定 ...

  6. C#获取图片扩展名

    代码: private string GetImageExtension(MemoryStream ms) { try { Image image = Image.FromStream(ms); if ...

  7. c# 后台GET、POST、PUT、DELETE传输发送json数据

    一.Get 方式传输 //url为请求的网址,param参数为需要查询的条件(服务端接收的参数,没有则为null) //返回该次请求的响应 public string HttpGet(string u ...

  8. HBase – 探索HFile索引机制

    本文由  网易云发布. 作者: 范欣欣 本篇文章仅限内部分享,如需转载,请联系网易获取授权. 01 HFile索引结构解析 HFile中索引结构根据索引层级的不同分为两种:single-level和m ...

  9. java—实现一个监听器HttpServletRequest的创建销毁、在线人数 (56)

    在JavaWeb中的监听器分类 在Javaweb中存在三个被监听对象: HttpServletRequest HttpSessoin ServletContext 监听者 被监听者 监听到事件对象 H ...

  10. ocp认证052最新题库-收集整理中-1

    1..Which two are true about the Archive (ARCn) processes?❑ A) They automatically delete obsolete arc ...