1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>javascript高级语法21-命令模式</title>
  6. </head>
  7. <body>
  8. <input type="text" id="flow" />
  9. <input type="button" id="" value="添加新流程" onclick="API.addFlow()" /><br>
  10. <input type="button" value="回退" onclick="API.re()" />
  11. <input type="button" value="重做" onclick="API.again()" />
  12. <div id="div01"></div>
  13.  
  14. <script id="uuid.js">
  15. //生成uuid的轮子
  16. /*
  17. uuid.js - Version 0.2
  18. JavaScript Class to create a UUID like identifier
  19. */
  20.  
  21. // On creation of a UUID object, set it's initial value
  22. function UUID(){
  23. this.id = this.createUUID();
  24. }
  25. // When asked what this Object is, lie and return it's value
  26. UUID.prototype.valueOf = function(){ return this.id; }
  27. UUID.prototype.toString = function(){ return this.id; }
  28. UUID.prototype.createUUID = function(){
  29. var dg = new Date(1582, 10, 15, 0, 0, 0, 0);
  30. var dc = new Date();
  31. var t = dc.getTime() - dg.getTime();
  32. var h = '-';
  33. var tl = UUID.getIntegerBits(t,0,31);
  34. var tm = UUID.getIntegerBits(t,32,47);
  35. var thv = UUID.getIntegerBits(t,48,59) + '1'; // version 1, security version is 2
  36. var csar = UUID.getIntegerBits(UUID.rand(4095),0,7);
  37. var csl = UUID.getIntegerBits(UUID.rand(4095),0,7);
  38. var n = UUID.getIntegerBits(UUID.rand(8191),0,7) +
  39. UUID.getIntegerBits(UUID.rand(8191),8,15) +
  40. UUID.getIntegerBits(UUID.rand(8191),0,7) +
  41. UUID.getIntegerBits(UUID.rand(8191),8,15) +
  42. UUID.getIntegerBits(UUID.rand(8191),0,15); // this last number is two octets long
  43. return tl + h + tm + h + thv + h + csar + csl + h + n;
  44. }
  45.  
  46. UUID.getIntegerBits = function(val,start,end){
  47. var base16 = UUID.returnBase(val,16);
  48. var quadArray = new Array();
  49. var quadString = '';
  50. var i = 0;
  51. for(i=0;i<base16.length;i++){
  52. quadArray.push(base16.substring(i,i+1));
  53. }
  54. for(i=Math.floor(start/4);i<=Math.floor(end/4);i++){
  55. if(!quadArray[i] || quadArray[i] == '') quadString += '0';
  56. else quadString += quadArray[i];
  57. }
  58. return quadString;
  59. }
  60.  
  61. UUID.returnBase = function(number, base){
  62.  
  63. 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'];
  64. if (number < base) var output = convert[number];
  65. else {
  66. var MSD = '' + Math.floor(number / base);
  67. var LSD = number - MSD*base;
  68. if (MSD >= base) var output = this.returnBase(MSD,base) + convert[LSD];
  69. else var output = convert[MSD] + convert[LSD];
  70. }
  71. return output;
  72. }
  73. UUID.rand = function(max){
  74. return Math.floor(Math.random() * max);
  75. }
  76.  
  77. </script>
  78. <script id="keymaster.js">
  79. //获取键盘事件的轮子
  80. (function(a) {
  81. function h(a, b) {
  82. var c = a.length;
  83. while (c--) if (a[c] === b) return c;
  84. return -1
  85. }
  86. function i(a) {
  87. var b, g, i, j, k;
  88. b = a.keyCode;
  89. if (b == 93 || b == 224) b = 91;
  90. if (b in d) {
  91. d[b] = !0;
  92. for (i in f) f[i] == b && (l[i] = !0);
  93. return
  94. }
  95. if (!l.filter.call(this, a)) return;
  96. if (!(b in c)) return;
  97. for (j = 0; j < c[b].length; j++) {
  98. g = c[b][j];
  99. if (g.scope == e || g.scope == "all") {
  100. k = g.mods.length > 0;
  101. for (i in d) if (!d[i] && h(g.mods, +i) > -1 || d[i] && h(g.mods, +i) == -1) k = !1;
  102. (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))
  103. }
  104. }
  105. }
  106. function j(a) {
  107. var b = a.keyCode,
  108. c;
  109. if (b == 93 || b == 224) b = 91;
  110. if (b in d) {
  111. d[b] = !1;
  112. for (c in f) f[c] == b && (l[c] = !1)
  113. }
  114. }
  115. function k() {
  116. for (b in d) d[b] = !1;
  117. for (b in f) l[b] = !1
  118. }
  119. function l(a, b, d) {
  120. var e, h, i, j;
  121. d === undefined && (d = b, b = "all"), a = a.replace(/\s/g, ""), e = a.split(","), e[e.length - 1] == "" && (e[e.length - 2] += ",");
  122. for (i = 0; i < e.length; i++) {
  123. h = [], a = e[i].split("+");
  124. if (a.length > 1) {
  125. h = a.slice(0, a.length - 1);
  126. for (j = 0; j < h.length; j++) h[j] = f[h[j]];
  127. a = [a[a.length - 1]]
  128. }
  129. a = a[0], a = g[a] || a.toUpperCase().charCodeAt(0), a in c || (c[a] = []), c[a].push({
  130. shortcut: e[i],
  131. scope: b,
  132. method: d,
  133. key: e[i],
  134. mods: h
  135. })
  136. }
  137. }
  138. function m(a) {
  139. var b = (a.target || a.srcElement).tagName;
  140. return b != "INPUT" && b != "SELECT" && b != "TEXTAREA"
  141. }
  142. function n(a) {
  143. e = a || "all"
  144. }
  145. function o() {
  146. return e || "all"
  147. }
  148. function p(a) {
  149. var b, d, e;
  150. for (b in c) {
  151. d = c[b];
  152. for (e = 0; e < d.length;) d[e].scope === a ? d.splice(e, 1) : e++
  153. }
  154. }
  155. function q(a, b, c) {
  156. a.addEventListener ? a.addEventListener(b, c, !1) : a.attachEvent && a.attachEvent("on" + b, function() {
  157. c(window.event)
  158. })
  159. }
  160. var b, c = {},
  161. d = {
  162. 16: !1,
  163. 18: !1,
  164. 17: !1,
  165. 91: !1
  166. },
  167. e = "all",
  168. f = {
  169. "⇧": 16,
  170. shift: 16,
  171. "⌥": 18,
  172. alt: 18,
  173. option: 18,
  174. "⌃": 17,
  175. ctrl: 17,
  176. control: 17,
  177. "⌘": 91,
  178. command: 91
  179. },
  180. g = {
  181. backspace: 8,
  182. tab: 9,
  183. clear: 12,
  184. enter: 13,
  185. "return": 13,
  186. esc: 27,
  187. escape: 27,
  188. space: 32,
  189. left: 37,
  190. up: 38,
  191. right: 39,
  192. down: 40,
  193. del: 46,
  194. "delete": 46,
  195. home: 36,
  196. end: 35,
  197. pageup: 33,
  198. pagedown: 34,
  199. ",": 188,
  200. ".": 190,
  201. "/": 191,
  202. "`": 192,
  203. "-": 189,
  204. "=": 187,
  205. ";": 186,
  206. "'": 222,
  207. "[": 219,
  208. "]": 221,
  209. "\\": 220
  210. };
  211. for (b = 1; b < 20; b++) f["f" + b] = 111 + b;
  212. for (b in f) l[b] = !1;
  213. 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)
  214. })(this);
  215. </script>
  216. <script>
  217. /*命令模式:
  218. * 用于消除调用者和接收者之间的耦合的模式
  219. * 并且可以对(调用这个过程进行留痕操作)
  220. * 不能乱用这个模式,它会使简单调用的写法变得非常复杂和难以理解
  221. * 当你的业务出现了回退操作,重做操作等需求的时候考虑用这个模式
  222. */
  223. /*需求:
  224. 有一个添加流程的按钮,单机的时候添加一个新的文本当做流程的描述
  225. 有返回 重做两个按钮,完成相应任务。
  226. */
  227. function manager(){
  228. this.addFlow = function(id,text){
  229. //1.得到目标节点
  230. var div = document.getElementById("div01");
  231. var newFlow = document.createElement("div");
  232. newFlow.setAttribute("id",id);
  233. newFlow.innerHTML = text;
  234. div.appendChild(newFlow);
  235. }
  236. }
  237. //为对象建立命令访问库
  238. manager.prototype.excute = (function(){
  239. //命令对象
  240. return function(command){
  241. return this[command.method](command.id,command.value)
  242. }
  243. })()
  244. //初始化主类
  245. var ma = new manager();
  246. //用于存储调用对象命令的集合。
  247. var commands = new Array();
  248. //集合的游标
  249. var index = commands.length;
  250. //客户端
  251.  
  252. var API = function(){
  253. this.addFlow = function(){
  254. //把调用封装起来
  255. var command = {
  256. method:"addFlow",
  257. id:new UUID().createUUID(),
  258. value:document.getElementById("flow").value,
  259. }
  260. //把调用对象保存起来,用于回退和重做
  261. commands.push(command);
  262. //重新定位游标
  263. index = commands.length;
  264. //调用
  265. ma.excute(command);
  266.  
  267. }
  268. //返回
  269. this.re = function(){
  270. if(index-1<0){
  271. alert("已经到最后一步了!")
  272. }else{
  273. all = document.getElementById("div01").childNodes;
  274. document.getElementById("div01").removeChild(all[all.length-1]);
  275. index = index - 1;
  276. }
  277. }
  278. //重做
  279. this.again = function(){
  280. if(index>=commands.length){
  281. alert("已经到了最新一步了,不能继续重做了!")
  282. }else{
  283. var command = commands[index];
  284. ma.excute(command);
  285. index = index + 1;
  286. }
  287. }
  288. }
  289. //实例化api
  290. var API = new API();
  291.  
  292. //添加支持键盘事件
  293. key("ctrl+z",function(){
  294. API.re();
  295. })
  296. key("ctrl+shift+z",function(){
  297. API.again();
  298. })
  299. </script>
  300. </body>
  301. </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. 《全民无双》锁链刀光程序生成算法,即U3D——刀光轨迹插件的改进

    <全民无双>手游12月17日上线登录APPSTore付费榜前十,首先特别恭喜还在<全民无双>坚持奋战的老同事们,顺便技术分享一下以前参与项目时的工作 锁链刀软武器刀光轨迹 之前 ...

  2. Android-应用安装/替换/卸载/广播监听

    在上一篇博客Android-开关机的广播,中介绍了,如何订阅接收者,去接收系统发送的开机/关机广播, 而这篇博客是订阅接收者 去接收应用的(安装/替换/卸载) 三种广播 订阅 接收者 去接收 应用的 ...

  3. 基于SSH的网上图书商城-JavaWeb项目-有源码

    开发工具:Myeclipse/Eclipse + MySQL + Tomcat 项目简介: 技术:Java:JSP:JDBC,struts2,spring,hibernate数据库: mysqlweb ...

  4. JKS与P12证书互转

    keytool -importkeystore -srckeystore cacerts -srcstoretype JKS -deststoretype PKCS12 -destkeystore k ...

  5. EAS_AOP分布式事务

    在System.Transactions事务体系中,为事务提供了7种不同的隔离级别.这7中隔离级别分别通过 System.Transactions.IsolationLevel的7个枚举项表示. pu ...

  6. 转载:爬虫技术浅析(Python)

    http://drops.wooyun.org/tips/3915 0x00 前言 网络爬虫(Web crawler),是一种“自动化浏览网络”的程序,或者说是一种网络机器人.它们被广泛用于互联网搜索 ...

  7. WP8.1StoreApp(WP8.1RT)---添加推送功能和获取系统信息

    添加推送通知 1:Package.appxmanifest中的声明添加后台任务的推送通知权限 2:var channel = await PushNotificationChannelManager. ...

  8. Android - Telephony API 1.6

    SignalStrength: 1. public int getGsmSignalStrength() : GSM Signal Strength, valid values are (0-31, ...

  9. Hibernate 干货

    一 .hibernate概念: hibernate应用在javaee 三层框架中的dao层(web 层 --service层--dao层),在dao层实现对数据库的CRUD操作.hibernate是对 ...

  10. Java中运算符“|”和“||”以及“&”和“&&”区别

    1.“|”运算符:不论运算符左侧为true还是false,右侧语句都会进行判断,下面代码 int a =1,b=1; if(a++ == 1 | ++b == 2) System.out.printl ...