【第九章】 命令模式

命令模式的用途

一个执行某些特定事情的指令
常见的应用场景 : 有时候需要向某些对象发送请求,但并不知道请求的接受者是谁,也不知道被请求的操作是什么。此时希望用一种耦合的方式来设计程序,使得请求发送者和请求接受者能够消除彼此之间的耦合关系

命令模式实例

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 oBtn1 = document.getElementById('btn1')
var oBtn2 = document.getElementById('btn2')
var oBtn3 = document.getElementById('btn3')

// 执行命令的函数
var setCommand = function (button, command) {
button.onclick = function () {
command.execute();
}
};
// 提供的功能菜单
var MenuBar = {
refresh: function () {
console.log('刷新菜单目录');
}
};
var SubMenu = {
add: function () {
console.log('增加子菜单');
},
del: function () {
console.log('删除子菜单');
}
};
// 封装命令类
var RefreshMenuBarCommand = function (receiver) {
this.receiver = receiver
}
RefreshMenuBarCommand.prototype.execute = function () {
this.receiver.refresh();
}

var AddSubMenuCommand = function (receiver) {
this.receiver = receiver;
}
AddSubMenuCommand.prototype.execute = function () {
this.receiver.add();
};

var DelSubMenuCommand = function (receiver) {
this.receiver = receiver;
};
DelSubMenuCommand.prototype.execute = function () {
this.receiver.del()
};

//最后就是把命令接收者传入到 command 对象中,并且把 command 对象安装到 button 上面
var refreshMenuBarCommand = new RefreshMenuBarCommand( MenuBar );
var addSubMenuCommand = new AddSubMenuCommand(SubMenu);
var delSubMenuCommand = new DelSubMenuCommand(SubMenu);
setCommand(btn1, refreshMenuBarCommand); // 刷新菜单目录
setCommand(btn2, addSubMenuCommand); // 增加子菜单
setCommand(btn3, delSubMenuCommand); // 删除子菜单

JavaScript中的命令模式

1
2
3
4
5
6
7
8
9
10
11
// ...
var RefreshMenuBarCommand = function (receiver) {
return {
execute: function(){
receiver.refresh()
}
}
}
// ....
var refreshMenuBarCommand = RefreshMenuBarCommand( MenuBar );
setCommand( btn1, refreshMenuBarCommand ); // 刷新菜单目录

宏命令

是一组命令的集合,通过执行宏命令的方式,可以一次执行一批命令

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
//下面我们看看如何逐步创建一个宏命令。首先,我们依然要创建好各种 Command:
var closeDoorCommand = {
execute: function(){
console.log( '关门' );
}
};
var openPcCommand = {
execute: function(){
console.log( '开电脑' );
}
};
/*接下来定义宏命令 MacroCommand,它的结构也很简单。macroCommand.add 方法表示把子命令添加进宏命令对象,当调用宏命令对象的 execute 方法时,会迭代这一组子命令对象,并且依次执行它们的 execute 方法:*/
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();

智能命令与傻瓜命令

1
2
3
4
5
var closeDoorCommand = { 
execute: function(){
console.log( '关门' );
}
};

closeDoorCommand 中没有包含任何 receiver 的信息,它本身就包揽了执行请求的行为,这跟我们之前看到的命令对象都包含了一个 receiver 是矛盾的。 一般来说,命令模式都会在 command 对象中保存一个接收者来负责真正执行客户的请求,这种情况下命令对象是“傻瓜式”的,它只负责把客户的请求转交给接收者来执行,这种模式的好处是请求发起者和请求接收者之间尽可能地得到了解耦。

但是我们也可以定义一些更“聪明”的命令对象,“聪明”的命令对象可以直接实现请求,这样一来就不再需要接收者的存在,这种“聪明”的命令对象也叫作智能命令。没有接收者的智能命令,退化到和策略模式非常相近,从代码结构上已经无法分辨它们,能分辨的只有它们意图的不同。策略模式指向的问题域更小,所有策略对象的目标总是一致的,它们只是达到这个目标的不同手段,它们的内部实现是针对“算法”而言的。而智能命令模式指向的问题域更广,command对象解决的目标更具发散性。命令模式还可以完成撤销、排队等功能。

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2019-2023 John Doe
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信