最近比较忙,一直没有更新博客了,今天还算比较空闲,就看了下设计模式中的命令模式
,并记录下来~
命令模式就好比你现在在外面,看到天色不对,好像要下雨,然后你自己又有东西晒在外面,这时就蛋疼了,好在你室友在寝室里,所以,你可以打个电话给室友,如果下雨,就叫他帮忙收一下衣物。期间你不用知道他在天开始下雨之前他在做什么,你只要知道一旦天开始下雨,他就会记得帮你收衣服。
而这些衣服就是命令模式中的命令对象
。
命令模式的用途
命令模式中的命令
就是一个执行某些特定事情的指令
其使用场景为:有时候需要向某些对象发送请求,但是不知道请求的接受者是谁,也不知道被请求的操作是什么,此时希望以一种松耦合的方式来设计程序,使得请求发送者和请求接受者能够消除彼此之间的耦合关系。
就拿刚才收衣服的例子来说,我向室友发送请求,但是完全不知道他以一种怎样的方式来收衣服,也许他在下雨之前就有事出去了,然后他就又委托另一个人来帮我收衣服,而我同样不需要知道他叫的人是怎样帮我收衣服的。命令模式
把我需要收衣服的请求封装成一个命令对象
,这个对象可以四处传递,就好比我室友有事他就叫了别的人来帮忙。从而解开了请求调用者与请求接收者之间的耦合关系。
命令模式的例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>命令模式的例子</title> </head> <body> <button id='btn1'>按钮1</button> <button id='btn2'>按钮2</button> <button id='btn3'>按钮3</button> <script type="text/javascript" src='js/demo1.js'></script> </body> </html>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| window.onload = function(){ var btn1 = document.getElementById('btn1'), btn2 = document.getElementById('btn2'), btn3 = document.getElementById('btn3');
var setCommand = function(btn , command){ btn.onclick = function(){ command.execute(); } };
var MenuBar = { refresh: function(){ console.log('刷新菜单') } };
var Submenu = { add:function(){ console.log('增加子菜单') }, del:function(){ console.log('删除子菜单') } };
var RefreshBarCommand = function(reciver){ this.reciver = reciver; }; RefreshBarCommand.prototype.execute = function(){ this.reciver.refresh(); };
var AddSubMenuCommand = function(reciver){ this.reciver = reciver; } AddSubMenuCommand.prototype.execute = function(){ this.reciver.add(); };
var DelSubMenuCommand = function(reciver){ this.reciver = reciver; }; DelSubMenuCommand.prototype.execute = function(){ this.reciver.del(); }
var refreshCommand = new RefreshBarCommand(MenuBar), addCommand = new AddSubMenuCommand(Submenu), delCommand = new DelSubMenuCommand(Submenu);
setCommand(btn1,refreshCommand); setCommand(btn2,addCommand); setCommand(btn3,delCommand); }
|
JS中的命令模式
上面的实现是使用传统的面向对象的方式写的,同样,在js中可以使用闭包进行实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| window.onload = function(){
var btn1 = document.getElementById('btn1'), btn2 = document.getElementById('btn2'), btn3 = document.getElementById('btn3');
var setCommand = function(btn ,func){ btn.onclick = function(){ func(); } };
var MenuBar = { refresh:function(){ console.log("刷新菜单") } };
var RefreshBarCommand = function(reciver){ return function(){ reciver.refresh(); } };
var refreshCommand = RefreshBarCommand(MenuBar);
setCommand(btn1,refreshCommand) }
|
撤销与重做
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| window.onload = function(){
var Ryu = { attack : function(){ console.log('攻击') }, defense:function(){ console.log('防御') }, jump:function(){ console.log('跳跃') }, crouch:function(){ console.log('蹲下') } };
var makeCommand = function(reciver,states){ return function(){ reciver[states](); } };
var commands = { '119':'jump', '115':'crouch', '97':'defense', '100':'attack' };
var commandsStack = [];
document.onkeypress = function(ev){ var keyCode = ev.keyCode, command = makeCommand(Ryu,commands[keyCode]);
if(command){ command(); commandsStack.push( command ); } }
document.getElementById('btn1').onclick = function(){ var command; while( command = commandsStack.shift()){ command(); } }
}
|
宏命令
宏命令
是一组命令的集合,通过执行宏命令,可以一次执行一批命令。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| window.onload = function(){ var closeDoorCommand = { execute:function(){ console.log('关门') } };
var openPcCommand = { execute:function(){ console.log('开电脑') } };
var openQqCommand = { execute : function(){ console.log('开QQ') } };
var MacroCommand = function(){ return { commandsList : [], add:function(command){ this.commandsList.push(command ) }, execute:function(){ for(var i=0,command;command=this.commandsList[i++];){ command.execute(); } } } };
var macroCommand = MacroCommand(); macroCommand.add(closeDoorCommand); macroCommand.add(openPcCommand); macroCommand.add(openQqCommand);
macroCommand.execute();
}
|