实现JavaScript API包装器

时间:2012-02-13 02:14:31

标签: javascript design-patterns

任何人都可以建议一种可用于编写JavaScript API 包装器的模式,其中多个实现之间没有共享代码?我们的想法是为客户端消费者提供一个包装API,用于运行时确定的许多可能API之一。 API调用可以是已经在应用程序环境中的对象/库,也可以是Web服务调用。

以下伪代码是我考虑过的两种方法:

单片解决方案

var apiWrapper = {
      init: function() {
          // *runtime* context of which API to call
          this.context = App.getContext(); 
      },
      getName: function() {
           switch(context) {
             case a:
               return a.getDeviceName() // real api call
             case b:
               return b.deviceName // real api call
             etc...
           }
      // More methods ...
    }
}

优点:可以为库使用者维护一致的API。

缺点:会导致庞大的整体库,难以维护。

模块解决方案

init.js

// set apiWrapper to the correct implementation determined at runtime
require([App.getContext()], function(api) {
  var apiWrapper = api;
});

module_a.js

// Implementation for API A
define(function() {
  var module = {
      getName: function() {
         return deviceA.getDeviceName();
       }
  };
  return module;
});

module_b.js

// Implementation for API B
define(function() {
  var module = {
      getName: function() {
         // could also potentially be a web service call
         return deviceB.getName;
       }
  };
  return module;
});

优点:更易于维护。

缺点:开发人员需要注意API保持一致。不是特别干。

这种情况下, Interface 的某些内容会很有用,但据我所知,没有办法在Js中强制执行合同。

这种问题是否有最佳实践方法?

3 个答案:

答案 0 :(得分:4)

真是巧合,有人​​在那里做我正在做的事情!最近,我一直在研究JS应用程序模式,我正在探索模块化模式。

我从this artice开始,它有很多链接引用其他JS开发人员。

最好采用模块化方式:

  • 主要是为了避免网站两个部分之间的依赖关系
  • 虽然可以依赖另一个,但它们“松散耦合”。
  • 为了建立一个网站,它应该在你撕开它时不会破坏
  • 另外,您需要单独测试部件而不使用其他所有部件
  • 轻松交换底层库(jQuery,dojo,mootools等),而不会实际影响现有模块(因为您正在构建我们自己的API)。
  • 如果您需要更改/升级API(或更改底层库),您只需触摸API“支持”而不是API,也不会重新编码使用它的部分

这里是我经历过的链接(主要是视频),它们传达了模块化方法的全部内容以及为什么要使用它:

答案 1 :(得分:3)

第二种方法更好,因为它是模块化的,您或第三方可以轻松扩展它以包含其他服务。 “API保持一致”的观点并不是那么有效,因为正确的单元测试可以使事情保持一致。

第二种方法也是未来的证据,因为你不知道为服务C实现说getName可能需要做些什么难以想象的事情,在这种情况下,最好有一个单独的module_c.js整体单一模块中的并发症而不是意大利面条代码。

对于真实接口IMO的需求并不那么重要,单元测试的文档化界面就足够了。

答案 2 :(得分:2)

我去了模块化解决方案。虽然没有内置的方法来强制执行合同,但你仍然可以决定一个,然后去TDD并构建一个测试模块的测试套件。接口合规性。

然后,您的测试套件基本上会采用具有显式接口的语言编译的角色:如果接口未正确实现,则会抱怨。