Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 命令模式:发光_Javascript_Design Patterns - Fatal编程技术网

Javascript 命令模式:发光

Javascript 命令模式:发光,javascript,design-patterns,Javascript,Design Patterns,我正在探索命令模式,并试图找出这种模式的实际好处。 我读过以下文章: 在盯着它看了足够长的时间之后,我仍然没有看到实施的好处。让我澄清我不明白的地方 我们有以下命令对象: (function(){ var CarManager = { // request information requestInfo: function( model, id ){ return "The information for " + model + " with ID

我正在探索命令模式,并试图找出这种模式的实际好处。
我读过以下文章:
在盯着它看了足够长的时间之后,我仍然没有看到实施的好处。让我澄清我不明白的地方

我们有以下命令对象:

(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 + " ) ";
      }

    };

})();  
执行人:

CarManager.execute = function ( name ) {
    return CarManager[name] && CarManager[name].apply( CarManager, [].slice.call(arguments, 1) );
};
文章说,这就是我们想要实现的目标:

CarManager.execute( "buyVehicle", "Ford Escort", "453543" );  
这就是我的问题所在:

看看上面的代码,调用 CarManager通过直接访问对象来管理方法。我们都会 原谅我认为这在技术上没有什么问题, 它是完全有效的JavaScript。然而,在某些情况下 这可能是不利的

例如,想象一下,如果CarManager背后的核心API发生了变化。 这将需要所有对象直接访问其中的这些方法 我们的应用程序也需要修改。这可以看作是一个层 耦合,这有效地违背了 尽可能地松耦合对象。相反,我们可以解决这个问题 通过进一步抽象API来解决此问题

我看不到的是,该解决方案在以下方面有何益处:

CarManager.buyVehicle("Ford Escort", "453543");  
“如果核心API发生变化”是什么意思?我假设他们讨论的是接口,即命令对象的方法及其实现。但是,如果它们中的任何一个发生了变化,那么调用方法的方式似乎不会发生任何变化(无论是否使用execute,如果方法名称发生变化,这两种方法都将不起作用)。
另外,我看不出
execute
方法如何解耦任何东西。无论是调用
execute
,还是直接执行方法,调用对象都需要引用命令对象。
此外,在本文中(请参阅VisualScheme),它们提到了客户机、接收方、调用方和命令对象。在示例中,我只看到两个对象(?)

有人能启发我吗

使用
.execute('methodName',…)
,您可以在不影响其公共接口的情况下更改基础方法名称

CarManager.execute('buyVehicle', 'Ford Escort')
可能真的会打电话

this.purchase(car)
在引擎盖下


也就是说,我从来没有真正看到过在野外执行
。但是,在许多jQuery插件中确实可以看到这种模式,因为它允许插件只占据
fn
名称空间中的一个位置,但执行大量命令。Ex
var-date=$(“#myEl”).datepicker('getDate')
一些一般概念:

1) 命令模式允许您为某个操作定义一个“单一入口点”

2) 这是一种构建用户GUI的干净方法:收集给定命令所需的所有信息并执行它。从命令结构中创建菜单结构

3) 可以从任何位置调用此操作。您不必使用特殊类的实例

4) 这是一种非常严格的方式来约束权利,并迫使任何行动沿着你指定的路线进行


5) 此外,这种解耦方法允许您定义宏和某种“脚本化流程”。我不知道你是否用MsAccess做过什么。那里的宏编码可以称为“命令模式”。我认为这种解释没有抓住要点。用于具体化方法调用(“操作”),以便以编程方式处理它们。例如,您可以将命令名存储在一个数组中,然后依次执行,或者在底层API(
execute
函数)中记录并存储它们以供回放

当然,JS已经是相当动态的了,这并没有多大变化(您总是可以使用括号表示法按名称执行方法),但是在
execute
函数中,方法名可以作为字符串使用,这样您就可以对它做些事情了,否则您就需要ES6代理

如果API发生更改,那么使用它的代码当然也需要更改。
execute
方法甚至可能会适得其反,因为它无法立即确定字符串参数是否是需要更改的方法名称(重构工具不喜欢这样),甚至可能不会在使用错误名称调用它时引发异常

我想这篇文章试图说明的一点是,当您已经有了这个命令模式时,facade更容易实现。可以通过编程方式处理方法名和参数

假设
buyVehicle
方法更改为
buyCar
方法。您以前可以通过以下方式提供向后兼容性:

CarManager.buyVehicle = CarManager.buyCar;
您可以使用命令模式插入行

if (name == "buyVehicle")
    name = "buyCar";

中执行
方法。虽然没有太大的优势,但它可能适用于更复杂的情况。

在这种情况下,是否会从
buyVehicle
中调用this.purchase(car)
?在那种情况下,我还是看不出有什么区别。。。如果我们将方法名作为字符串传递,与直接调用它相比,它实际上有什么好处?
buyVehicle
仅作为键存在;
execute
方法将其映射到它应该调用的任何内部函数,从而允许公共API保持不变,而不管内部方法的名称如何。谢谢,我现在明白了:虽然示例对我来说不太明显,但我理解键作为字符串可用背后的原因,而不是直接应用方法名。我无法想象大多数代码都是按照本文提到的方式编写的。阅读、理解和调试将是无望的迟钝,并且没有理由从解析器手中拿走一个方法名,并在大多数情况下将其转移到运行时评估。有时,您可能会在字符串中实际包含一个方法名,但您可以只执行
obj[met]