命令模式(Command)的定义是:用于将一个请求封装成一个对象,从而使你可用不一样的请求对客户进行参数化;对请求排队或者记录请求日志,以及执行可撤销的操做。也就是说改模式旨在将函数的调用、请求和操做封装成一个单一的对象,而后对这个对象进行一系列的处理。此外,能够经过调用实现具体函数的对象来解耦命令对象与接收对象。函数
咱们来经过车辆购买程序来展现这个模式,首先定义车辆购买的具体操做类:设计
$(function () {
var CarManager = {
// 请求信息
requestInfo: function (model, id) {
return 'The information for ' + model +
' with ID ' + id + ' is foobar';
},
// 购买汽车
buyVehicle: function (model, id) {
return 'You have successfully purchased Item '
+ id + ', a ' + model;
},
// 组织view
arrangeViewing: function (model, id) {
return 'You have successfully booked a viewing of '
+ model + ' ( ' + id + ' ) ';
}
};
})();
来看一下上述代码,经过调用函数来简单执行manager的命令,然而在一些状况下,咱们并不想直接调用对象内部的方法。这样会增长对象与对象间的依赖。如今咱们来扩展一下这个CarManager 使其可以接受任何来自包括model和car ID 的CarManager对象的处理请求。根据命令模式的定义,咱们但愿实现以下这种功能的调用:日志
CarManager.execute({ commandType: "buyVehicle", operand1: 'Ford Escort', operand2: '453543' });
根据这样的需求,咱们能够这样啦实现CarManager.execute方法:code
CarManager.execute = function (command) {
return CarManager[command.request](command.model, command.carID);
};
改造之后,调用就简单多了,以下调用均可以实现(固然有些异常细节仍是须要再完善一下的):orm
CarManager.execute({ request: "arrangeViewing", model: 'Ferrari', carID: '145523' });
CarManager.execute({ request: "requestInfo", model: 'Ford Mondeo', carID: '543434' });
CarManager.execute({ request: "requestInfo", model: 'Ford Escort', carID: '543434' });
CarManager.execute({ request: "buyVehicle", model: 'Ford Escort', carID: '543434' });
命令模式比较容易设计一个命令队列,在需求的状况下比较容易将命令计入日志,而且容许接受请求的一方决定是否须要调用,并且能够实现对请求的撤销和重设,并且因为新增的具体类不影响其余的类,因此很容易实现。对象
但敏捷开发原则告诉咱们,不要为代码添加基于猜想的、实际不须要的功能,若是不清楚一个系统是否须要命令模式,通常就不要着急去实现它,事实上,在需求的时经过重构实现这个模式并不困难,只有在真正需求如撤销、恢复操做等功能时,把原来的代码重构为命令模式才有意义。blog