function add(x, y) { return x + y; }
function sub(x, y) { return x - y; }
function mul(x, y) { return x * y; }
function div(x, y) { return x / y; }
//Command
var Command = function (execute, undo, value) {
this.execute = execute;
this.undo = undo;
this.value = value;
}
//Concrete Command
var AddCommand = function (value) {
return new Command(add, sub, value);
};
var SubCommand = function (value) {
return new Command(sub, add, value);
};
var MulCommand = function (value) {
return new Command(mul, div, value);
};
var DivCommand = function (value) {
return new Command(div, mul, value);
};
// Receiver
var Calculator = function () {
//执行结果
var current = 0;
//执行历史
var commands = [];
function action(command) {
var name = command.execute.name;
return name.charAt(0).toUpperCase() + name.slice(1);
}
return {
execute: function (command) {
current = command.execute(current, command.value);
commands.push(command);
log.add(action(command) + ": " + command.value);
},
undo: function () {
var command = commands.pop();
current = command.undo(current, command.value);
log.add("Undo " + action(command) + ": " + command.value);
},
getCurrentValue: function () {
return current;
}
}
}
// log helper
var log = (function () {
var log = "";
return {
add: function (msg) { log += msg + "\n"; },
show: function () { console.log(log); log = ""; }
}
})();
//Client
function run() {
var calculator = new Calculator();
// issue commands
calculator.execute(new AddCommand(100));
calculator.execute(new SubCommand(24));
calculator.execute(new MulCommand(6));
calculator.execute(new DivCommand(2));
// reverse last two commands
calculator.undo();
calculator.undo();
log.add("\nValue: " + calculator.getCurrentValue());
log.show();
}
run();
设计思想:分离职责,包括执行命令、发布命令委托给不同的对象。使用一个简单的命令把具体命令(Concrete Command)和调用方法(receiver的execute方法)绑定在一起。
优点: 1. 具有相同接口的Command子对象(Concrete Command)可以根据需要轻松交互 1. 扩展/维护子对象(Concrete Command)变得非常容易,几乎不用改大量代码 1. 你可以创建一个具有队列系统的命令队列,例如上面的的命令具有撤销命令功能
缺点: 1. 必须要使用很多类目和对象才能完成目标,开发者必须要小心正确地开发这些类 1. 每一个独立的命令都是一个具体命令(Concrete Command)类,这样会增加大量的类去实现方法和维护