实现JavaScript API包装器

Bay*_*del 5 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 ...
    }
}
Run Code Online (Sandbox Code Playgroud)

优点:可以为库消费者维护一致的API.

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

模块解决方案

init.js

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

module_a.js

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

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;
});
Run Code Online (Sandbox Code Playgroud)

优点:更易于维护.

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

这将是一个沿着界面的东西有用的情况,但据我所知,没有办法在Js中强制执行合同.

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

Anu*_*yal 3

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

第二种方法也是面向未来的,因为你不知道你可能需要做哪些难以想象的事情来实现getName服务 C,在这种情况下,最好有一个单独的 module_c.js 包含所有复杂性,而不是单一的意大利面条代码模块。

在我看来,对真实接口的需求并不那么重要,带有单元测试的记录接口就足够了。