JavaScript设计模式-21.命令模式
<!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.命令模式的更多相关文章
- 再起航,我的学习笔记之JavaScript设计模式21(命令模式)
命令模式 概念描述 命令模式(Command): 将请求与实现解耦并封装成独立的对象,从而使不同的请求对客户端的实现参数化 示例代码 命令模式我们可以看成是将创建模块的逻辑封装在一个对象里,这个对象提 ...
- JavaScript设计模式之命令模式
一.命令模式概念 命令模式(Command)的定义是:用来对方法调用进行参数化处理和传送,经过这样处理过的方法调用可以在任何需要的时候执行.也就是说该模式旨在将函数的调用.请求和操作封装成一个单一的对 ...
- JavaScript设计模式之命令模式【命令解耦】
在讲解命令模式之前我们先来了解一个生活中的命令模式场景: 场景1: 医院看病抓药: 当你因为肾虚到医院看医生,医生一番操作之后得出结论:要吃个疗程[夏桑菊].[小柴胡](药名纯属虚构,真的肾虚就找医生 ...
- JavaScript 设计模式之命令模式
一.命令模式概念解读 1.命令模式概念文字解读 命令模式(Command)的定义是:用来对方法调用进行参数化处理和传送,经过这样处理过的方法调用可以在任何需要的时候执行.也就是说该模式旨在将函数的调用 ...
- JavaScript设计模式之----组合模式
javascript设计模式之组合模式 介绍 组合模式是一种专门为创建Web上的动态用户界面而量身制定的模式.使用这种模式可以用一条命令在多个对象上激发复杂的或递归的行为.这可以简化粘合性代码,使其更 ...
- 设计模式 ( 十三 ) 命令模式Command(对象行为型)
设计模式 ( 十三 ) 命令模式Command(对象行为型) 1.概述 在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需 ...
- 乐在其中设计模式(C#) - 命令模式(Command Pattern)
原文:乐在其中设计模式(C#) - 命令模式(Command Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 命令模式(Command Pattern) 作者:webabcd ...
- 面向对象设计模式_命令模式(Command)解读
在.Net框架中很多对象的方法中都会有Invoke方法,这种方法的设计实际是用了设计模式的命令模式, 模式图如下 其核心思路是将Client 向Receiver发送的命令行为进行抽象(ICommand ...
- 折腾Java设计模式之命令模式
博客原文地址 折腾Java设计模式之命令模式 命令模式 wiki上的描述 Encapsulate a request as an object, thereby allowing for the pa ...
随机推荐
- java并发编程实战:第四章----对象的组合
一.设计线程安全的类 找出构造对象状态的所有变量(若变量为引用类型,还包括引用对象中的域) 约束状态变量的不变性条件 建立对象状态的并发访问管理策略(规定了如何维护线程安全性) 1.收集同步需求(找出 ...
- 23 DesignPatterns学习笔记:C++语言实现 --- 2.1 Bridge
23 DesignPatterns学习笔记:C++语言实现 --- 2.1 Bridge 2016-07-22 (www.cnblogs.com/icmzn) 模式理解
- mysql查看数据库性能常用命令
mysql> show global status; 可以列出MySQL服务器运行各种状态值,另外,查询MySQL服务器配置信息语句: mysql> show variables; 一.慢 ...
- python 中为什么不需要重载
函数重载主要是为了解决两个问题. (1)可变参数类型. (2) 可变参数个数. 另外,一个基本的设计原则是,仅仅当两个函数除了参数类型和参数个数不同以外,其功能是完全相同的,此时才使用函数重载,如果两 ...
- TSQL--标示列、GUID 、序列
--1. IDENTIY 列不能为空,不能设默认值,创建后不能使用ALTER TABLE TableName ALTER COLUMN修改,每张表只能有一个自增列--2. 查看当前值:SELECT I ...
- Nutch 问题杂记
1. 如何绕过目标站点的robots.txt限制 多数站点都是只允许百度.google等搜索引擎抓取的,所以会在robots.txt里限制其他爬虫. nutch自然是会遵循robots协议的,但是我们 ...
- CheckBox使用记录
页面显示 页面代码 <div> <div><input type="checkbox" value="" class=" ...
- SpringMvc+ajax 实现json格式数据传递
传JSON对象 前端 function test () { var param = {username : "yitop"}; $.ajax({ timeout : 20000, ...
- PHP一句话木马Webshell变形免杀总结
0×00 前言 大部分Webshell查杀工具都是基于关键字特征的,通常他们会维护一个关键字列表,以此遍历指定扩展名的文件来进行扫描,所以可能最先想到的是各种字符串变形,下面总结了一些小的方法,各种不 ...
- su: Authentication failure 的解决方案
原因是:ubuntu默认不允许使用root登录,因此初始root账户是不能使用的,需要在普通账户下利用sudo权限修改root密码. 解决方案很简单:设置一个root密码就行了.注意是sudo 而不是 ...