命令模式
命令模式的一般性思想是,提供一个方法将分发命令的责任与命令的执行相分离,将职责委派给不同的对象。
聪明的实现,简单的命令对象将行为与该对象希望调用的行为绑定在一起。他们始终包含一个执行操作,所有的命令对象具有相同的接口可以在需要的时候轻易的替换,并且这被认为是该模式的巨大好处之一。
为了演示命令模式,我们将创建一个简单的汽车采购服务。
(function(){
var carManager = {
// request information
requestInfo: function( model, id ){
return "The information for " + model + " with ID " + id + " is foobar";
},
// purchase the car
buyVehicle: function( model, id ){
return "You have successfully purchased Item " + id + ", a " + model;
},
// arrange a viewing
arrangeViewing: function( model, id ){
return "You have successfully booked a viewing of " + model + " ( " + id + " ) ";
}
};
})();
这个carManage
的方法被直接调用是可行的,至少从js语法上说是有效的。但是有时这样写带来一些不方便之处。
例如,想象一下如果carManage
的核心API发生了变化,那么所有调用这个API的地方都得跟着做相应的修改。这可以被看作是一个耦合层,违反了面向对象设计的松耦合原则,我们可以进一步抽象API来解决这个问题。
接下来让我们扩展这个carManage以便我们可以通过在我们的应用中使用命令模式达到如下效果:在carManage
中接受任何命名的方法作为参数可被执行;可以传递任何可以被利用的数据,例如Id与model。
它可能长得像这样。
carManager.execute( "buyVehicle", "Ford Escort", "453543" );
按照这个结构,我们现在应该添加carmanager.execute方法的定义如下:
carManager.execute = function ( name ) {
return carManager[name] && carManager[name].apply( carManager, [].slice.call(arguments, 1) );
};
我们最终的调用可能如下:
carManager.execute( "arrangeViewing", "Ferrari", "14523" );
carManager.execute( "requestInfo", "Ford Mondeo", "54323" );
carManager.execute( "requestInfo", "Ford Escort", "34232" );
carManager.execute( "buyVehicle", "Ford Escort", "34232" );