JavaScript设计模式-21.命令模式

  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>

 

posted @ 2017-07-16 21:13  橙云生  阅读(192)  评论(0编辑  收藏  举报