Синглтоны в JS и как их использовать

Привет команда,

Сегодня я хотел бы рассказать о синглтонах и о том, как мы используем их на ежедневной основе.
Итак, паттерн синглтон позволяет нам создавать единственный экземпляр определенного класса. Для каких целей он может быть полезен? Мы используем их для:

  • сервисы обмена данными, которые заботятся о передаче данных в/из базовых сервисов
  • сервисы обработки данных, которые могут быть инстанцированы только один раз при запуске приложения
  • кэш-сервисы
  • цели тестирования

Например, мы решили продолжить работу с ранее описанным кэш-сервисом (https://dev.to/frozer/vanilla-js-data-cache-service-1ei2), по некоторым причинам нам не нужно несколько кэш-сервисов.
кэш-сервисов в нашем приложении, так как же нам создать одиночный?

Давайте начнем с очень простого кода для создания синглтона:

class SingletoneService {
  static instance;

  getInstance(args) {
    if (!SingletoneService.instance) {
      SingletoneService.instance = new SingletoneService(...args);
    }

    return SingletoneService.instance;
  }

  constructor(args) {
    // do something with args
  }

  doSomething() {
    // do something
  }
}
Вход в полноэкранный режим Выйти из полноэкранного режима

Итак, как это работает? В основной программе мы можем создать экземпляр синглтона, вызвав этот метод getInstance с аргументами (если они нам нужны):

function main() {
  const instance = SingletoneService.getInstance();

  instance.doSomething();
}
main();
Вход в полноэкранный режим Выйти из полноэкранного режима

Вызов метода getInstance проверяет наличие значения статического поля экземпляра класса SingletoneService, а затем инстанцирует новый объект на основе этого класса с помощью ключевого слова new. Если он существует, то просто возвращает существующий экземпляр.

Теперь, когда черновая реализация закончена, попробуйте перенести эту функциональность в наш CacheService:

class SomeServiceWithDataCache {
  static instance;

  getInstance(args) {
    if (!SomeServiceWithDataCache.instance) {
      SomeServiceWithDataCache.instance = new SomeServiceWithDataCache(...args);
    }

    return SomeServiceWithDataCache.instance;
  }

  constructor() {
    this.cache = {
      isLoading: false,
      expire: 0,
      data: null
    };
    this.cacheSubscriptions = [];
  }
  ...
}
Вход в полноэкранный режим Выход из полноэкранного режима

Также вы можете использовать синглтоны для инъекции зависимостей в ваш класс:

class DataProcessingService {
  // use existing DataCacheService instance by default
  constructor(cacheService = DataCacheService.getInstance()) {
    // do something in constructor)
  }
  ...
}
Войти в полноэкранный режим Выход из полноэкранного режима

Что позволяет реализовать изоляцию кода и принцип Open-Closed.

Оцените статью
devanswers.ru
Добавить комментарий