My Little World

命令模式

应用情景

有时候需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是什么。
此时希望用一种松耦合的方式设计软件,使得请求发送者和请求接收者能够消除彼此之间的耦合关系

主要思想

将命令接收者的具体执行函数存入 命令堆栈,命令发起者需要执行/撤销动作时,对堆栈进行处理
命令接收者可以以闭包形式被执行,也可以作为对象属性被执行到

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
//闭包形式
var setCommand = function(btn,fn){
btn.onclick = function(){
fn()
}
}
var MenuBar = {
refresh:function(){
console.log('refresh menu')
}
}
var RefreshMenuBarCommand = function(reciver){
return function(){reciver.refresh()}
}
var refreshMenuBarCommand = RefreshMenuBarCommand(Menubar)
setCommand(btn1,refreshMenuBarCommand)

//宏命令,组装一个可以一次性触发多个命令的命令;属性形式,统一使用execute触发
var MacroCommand = function(){
return {
commandsList:[],
add:function(command){
this.commandsList.push(command);
},
execute:function(){
for(var i=0,cammand;command = this.commandsList[i++];){
command.execute();
}
},
undo:function(){
for(var i=0,cammand;command = this.commandsList[i++];){
command.undo();
}
},

}
}
var closeDoorCom ={
execute:function(){
console.log('close door')
},
undo:function(){console.log('open door')}
}
var openTvCom ={
execute:function(){
console.log('open TV')
},
undo:function(){console.log('close Tv')}
}
var macroCommand = MacroCommand()
macroCommand.add(closeDoorCom)
macroCommand.add(openTvCom)
macroCommand.execute()
macroCommand.undo()

与策略区别

策略模式指向问题域更小,所有策略对象目标一致,他们只是达到这个目的的不同手段,内部实现针对‘算法’
命令对象解决的目标更具发散性,还可以完成撤销,排队等功能