Как правильно сделать точку входа в мой модуль, который содержит несколько классов? - PullRequest
1 голос
/ 18 апреля 2019

Я начал разрабатывать настольное приложение с узлом и электроном. У него есть пакет, который реализует соединение с некоторым API. Он структурирован как один базовый класс, и некоторые классы класса Derrived:

  • ApiBase
  • 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

  • я не уверен, что создание этих экземпляров каждый раз, когда требуется index.js, - это просто

Так что я хочу знать о некоторых подходах, которые я могу использовать здесь, потому что теперь я даже знаю, с чего начать исследования. Спасибо.

1 Ответ

1 голос
/ 19 апреля 2019

Я думаю, что вы определили некоторые из наиболее важных решений с этим:

проблема передачи параметра хоста конструкторам в index.js динамически

Конфигурация IMO и интерфейс являются важными факторами.Несмотря на то, что после факта его можно изменить, простой в настройке и использовании интерфейс поможет сократить использование вашей библиотеки.Как вы указали, конфигурация сейчас статична и очень хрупкая.Т.е. изменение 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-адрес, конфигурация является «неявной».ИМО это не интуитивно понятно и сложно документировать.Также это не является явным и требует, чтобы клиент просматривал код, чтобы увидеть переменные среды и поток создания экземпляров.

Я бы предпочел предоставить эти классы напрямую клиенту.Я бы посчитал этот подход «явным», так как он заставляет клиента явно настраивать / создавать экземпляры ваших компонентов.Я думаю, это все равно, что предоставить вашим клиентам примитивы и позволить им составлять, создавать и настраивать их так, как они хотят:

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

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

Это автоматически именует API-интерфейсы за его функциями (auth | tasks) И требуетчто клиент создает экземпляры классов перед использованием:

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

Это еще больше расширяет конфигурацию в архитектуре. Это вынуждает клиента решать, как он хочет получить 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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...