javascript - 如何正确地为包含多个类的模块创建一个入口点?

标签 javascript node.js oop module

我已经开始使用 Node 和电子开发桌面应用程序。它有一个包,正在实现与一些API的连接。它的结构是一个基类和一些派生类,结构如下:

  • API 库
  • ApiAuth 扩展了 ApiBase
    • ApiAuth.login()
    • ApiAuth.logout()
    • 等...
  • ApiTasks 扩展了 ApiBase
    • ApiTasks.getTaskList()
    • 等...
  • 等...

现在,我想以一种方便的方式在我的应用程序中使用这些类。所以我需要创建一些入口点,这将提供对我的 API 实现的访问。但是,我没有太多的经验来使它正确。

我想过这样的事情:

index.js:

const ApiAuth = require('./amazing-time-api-auth');
const ApiTasks = require('./amazing-time-api-tasks');

apiAuth = new ApiAuth('www.sample-host.com');
apiTasks = new ApiTasks('www.sample-host.com');

module.exports = {
  login: apiAuth.login,
  logout: apiAuth.logout,
  getTaskList: apiTasks.getTaskList,
  etc...
}

在应用的某处:

const api = require("./lib/someApi");

// need to get task list for some reason

api.getTaskList(param1, param2)

但是我管理的这种方法存在一些问题:

  • 在index.js中动态传递host参数给构造函数是个问题

  • 我不确定每次都需要 index.js 创建这个实例是否正确

所以我想知道我可以在这里使用的一些方法,因为我现在甚至知道从哪里开始研究。谢谢。

最佳答案

我认为您确定了一些最关键的决定:

在index.js中动态传递host参数给构造函数是个问题

IMO 配置和接口(interface)是重要的考虑因素。尽管它可以在事后重构,但易于配置和使用的界面将有助于减少您的库的采用率。正如您所指出的,配置现在是静态的并且非常脆弱。即对 URL 的更改将级联到所有客户端并要求所有客户端更新。

第一个直观的替代方案可能是允许动态配置当前结构:

apiAuth = new ApiAuth(process.env.API_AUTH_URL || 'www.sample-host.com');
apiTasks = new ApiTasks(process.env.API_TASKS_URL || 'www.sample-host.com');

虽然这允许客户端动态配置 URL,但配置是“隐式的”。 IMO 这是不直观且难以记录的。此外,它不是显式的,需要客户端查看代码以查看环境变量和实例化流程。

我更愿意将这些类直接暴露给客户。我认为这种方法是“明确的”,因为它强制客户端明确配置/实例化您的组件。我认为这就像为您的客户提供原语并允许他们以他们想要的任何方式组合、构建和配置它们:

const ApiAuth = require('./amazing-time-api-auth');
const ApiTasks = require('./amazing-time-api-tasks');

module.exports = {
  auth: ApiAuth,
  tasks: ApiTasks
}

这会在其函数 (auth|tasks) 后面自动命名 api,并要求客户端在使用前实例化类:

const api = require("./lib/someApi");
const auth = new api.auth(process.env.SOMETHING, 'some-url');

这会拉取 configuration further out in the architecture.它强制客户端决定如何获取 URL 并显式实例化库。如果您的一位客户不使用登录/注销怎么办?在这种情况下,这可能会更灵活。

我不确定每次都需要 index.js 创建这个实例是否正确

如果实例化应该保持隐藏,另一种选择是提供一个构建器函数来封装它:

const ApiAuth = require('./amazing-time-api-auth');
const ApiTasks = require('./amazing-time-api-tasks');

apiAuth = new ApiAuth('www.sample-host.com');
apiTasks = new ApiTasks('www.sample-host.com');

module.exports = {
  auth: {
     build: (url) => {
        return new ApiAuth(url);
     }
  },
  tasks: {
    build: (url) => {
       return new ApiTasks(url);
    }
  }
}

这应该仍然隐藏每个类,但仍然允许客户端决定如何配置每个类:

const api = require("./lib/someApi");
const auth = api.auth.build('my-url');
auth.login();

关于javascript - 如何正确地为包含多个类的模块创建一个入口点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55751251/

相关文章:

python - 依赖于相同基础的抽象行为?

javascript - JS Contenteditable 下划线不起作用

javascript - 如何设置 jquery onclick 函数以仅针对可编辑表中的特定表列或类?

node.js - 检索 Couchbase 的所有记录(文档)

c++ - 什么时候应该使用友元类?

java - 如何继承两个类

javascript - jquery flot graph项目可以处理不连续点吗

javascript - 如何将谷歌浏览器的 .keyIdentifier 转换为合理的东西?

node.js - 使用 Node 的 http.get 函数获取 ECONNRESET 响应

node.js - 在 Node.JS 中使用 async/await 正确请求