我有一个关于书中command pattern explanation的问题 - 由addy osmani撰写的基本js设计模式。
(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 + " ) ";
}
/* The function that acts as a common point for function calls */
execute : function ( name ) {
return carManager[name] && carManager[name].apply( carManager, [].slice.call(arguments, 1) );
};
};
})();
以上是代码,作为模式解释的一部分。它会将execute作为模块的单个入口点,它将获得根据传递给它的参数调用的相应方法。
carManager.execute( "arrangeViewing", "Ferrari", "14523" );
carManager.execute( "requestInfo", "Ford Mondeo", "54323" );
carManager.execute( "requestInfo", "Ford Escort", "34232" );
carManager.execute( "buyVehicle", "Ford Escort", "34232" );
引用这本书:
如果carManager后面的核心API发生了变化。这需要所有人 对象直接访问我们的应用程序中的这些方法 也可以修改。这可以被视为一层耦合 有效地违背了松散耦合的OOP方法 对象尽可能多。相反,我们可以解决这个问题 进一步抽象API。
根据上述优势,execute
方法是作为其中一部分添加的图层。但正如您所看到的,即使实现这个额外的抽象层,也需要更改模块外部的方法调用,因为第一个参数引用了被调用的函数名称。
假设,模块的内部功能已从" arrangeViewing" to" arrangeViewing2",这将需要此模块的所有相关代码来改变
carManager.execute( "arrangeViewing", "Ferrari", "14523" );
到
carManager.execute( "arrangeViewing2", "Ferrari", "14523" );
除非我们不在执行函数代码中使用映射,否则将函数标签指向内部的实际函数。因此,上述代码示例所提到的优势是否毫无意义?
另外,根据本书上面引用的代码,我们不会将carManager
发布到其他模块的外部范围,以便能够使用它。此外,如果我们将执行作为单一入口点,为什么其他功能不能私有?
我的观点是正确的还是我遗漏了一些重要的东西?请帮帮我。
答案 0 :(得分:2)
通过Command模式解耦对于Java,c ++,c#等静态类型语言至关重要。但它在动态类型语言(如JavaScript)中并不那么重要,因为我们可以非常自由地传递任何方法。所以我也没有看到这方面的优势。
但Command具有本书中未提及的其他特性,例如Command可以作为系统中操作的单一事实来源,我们可以记录系统中发生的事情,我们可以创建优雅回滚的可能性机制,如果需要,为命令创建队列等。
顺便说一下,整个Redux架构是actually Command pattern,其中:
The Store = The Receiver
The Action = The Command
Dispatch = Executor
P.S。我发现沿着GoF书阅读Addy的书非常有用。