<!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. MFC中的一般经验之谈3

    Window消息可以分为三类:(1)标准Window消息(CWnd子类处理),(2)控制通知消息(CWnd子类处理),(3)命令消息(应用中的5类都可以).所有派生自CCmdObjec对象的类都可以处 ...

  2. CentOS 6.0下phpvod搭建教程(LAMP+phpvod)

    之所以安装CentOS是因为之前试过RedHat,但是发现RedHat在安装时,无法获取安装源,原因是RedHat系统没有在RHN注册. 网上的很多教程都说可以直接换用CentOS的源,可我小搞里一会 ...

  3. NideShop项目的安装部署教程

    本文档为微信小程序商城NideShop项目的安装部署教程,欢迎star NideShop商城api服务:https://github.com/tumobi/nideshop NideShop微信小程序 ...

  4. Python学习-12.Python的输入输出

    在Python中,输出使用print函数,之前用过了. 输入的话,则使用input函数. var = input() print('you input is' + var) 输入haha则将输出you ...

  5. .NET 匿名方法的BUG,请专家解答

    匿名方法是.NET 3.5之后的一个好东东,很多人使用,但是我在最近的工作当中发现了一个问题. 请专家解答 //list里存放10个数字 List<); ; i < ; i++) { li ...

  6. 介绍 ASP.NET Identity - ASP.NET 应用程序的成员身份认证系统

    ASP.NET Identity 是构建 ASP.NET web 应用程序的一种新的身份认证系统.ASP.NET Identity 可以让您的应用程序拥有登录功能,并可以轻松地自定义登录用户的相关数据 ...

  7. AngularJS Backbone.js Ember.js 对比

    看到一篇关于AngularJS Backbone Ember.js的对比,建议看一看 说说个人的观点(本人学艺不精,只是个人的观点,不保证观点完全正确,请轻拍): backbone.js 短小精悍,非 ...

  8. [Git00] Pro Git 一二章读书笔记

    记得知乎以前有个问题说:如果用一天的时间学习一门技能,选什么好?里面有个说学会Git是个很不错选择,今天就抽时间感受下Git的魅力吧.   Pro Git (Scott Chacon) 读书笔记:   ...

  9. iOS 使用 TestFlight 测试

    TestFlight 已经并入 Itunes connect. 测试方法: 1. itunes connect 上创建应用 2. xcode 里 archive 应用并 submit 到 itunes ...

  10. “全栈2019”Java第三章:安装开发工具IntelliJ IDEA

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...