TIP
命令模式中的命令指的是一个执行某些特定事情的指令。
# JavaScript中的命令模式
命令模式的由来,其实是回调函数的一个面向对象的替代品。和策略模式一样,命令模式也早已融入到了JavaScript语言中。
案例:菜单程序 假设我们正在编写一个用户界面程序,该用户界面上至少有数十个Button按钮。因为项目比价复杂,所以我们决定让某个程序员负责绘制这些按钮,而另外一些程序员则负责编写点击按钮后的具体行为,这些行为都将被封装在对象里。
var RefreshMenuBarCommand = function (receiver) {
return {
execute: function () {
receiver.refresh()
}
}
}
var setCommand = function (button, command) {
button.onclick = function () {
command.execute()
}
}
var MenuBar = {
refresh: function () {
console.log('刷新菜单界面')
}
}
var refreshMenuBarCommand = RefreshMenuBarCommand(MenuBar)
setCommand(button1, refreshMenuBarCommand)
# 撤销和重做
当需要撤销命令时,我们可以把所有执行过的命令都存储在一个历史列表中,然后倒序循环来依次执行这些命令的undo操作。
如果要撤销不可逆转的命令,我们可以记录命令日志,然后清楚搜索操作,把刚才执行过的命令全部重新执行一遍。
var Ryu = {
attack () {
console.log("攻击");
},
defense () {
console.log("防御");
},
jump () {
console.log("跳跃");
},
crouch () {
console.log("蹲下")
}
}
var makeCommand = function (receiver, state) {
return function () {
if (receiver[state]) {
receiver[state]();
}
}
}
const commands = {
"119": "jump",
"115": "crouch",
"97": "defense",
"100": "attack"
}
var commandStack = [];
document.onkeypress = function (ev) {
var keyCode = ev.keyCode,
command = makeCommand(Ryu, commands[keyCode]);
if (command) {
commandStack.push(command);
}
}
document.getElementById("replay").onclick = function () {
var command;
while (command = commandStack.shift()) {
command();
}
}
# 宏命令
TIP
宏命令是一组命令的集合,通过执行宏命令的方式,可以一次执行一批命令。
var closeDoorCommand = {
excute: function () {
console.log("关门");
}
}
var openPcCommand = {
excute: function () {
console.log("开电脑");
}
}
var openQQCommand = {
excute: function () {
console.log("登陆qq")
}
}
var macroCommand = (function () {
return {
commandList: [],
add: function (command) {
this.commandList.push(command);
},
excute: function () {
for (var i = 0, command; command = this.commandList[i++];) {
command.excute();
}
}
}
})()
macroCommand.add(closeDoorCommand);
macroCommand.add(openPcCommand);
macroCommand.add(openQQCommand);
macroCommand.excute();