Шаблон Singleton в JavaScript: основы работы

Singleton (или Одиночка) – один из самых известных шаблонов проектирования. Он предназначен для тех случаев, когда вам нужен только один экземпляр класса и не более. Этот один класс может быть менеджером ресурсов или глобальным поиском значений.

В этом мануале вы узнаете, что такое синглтоны и как лучше всего реализовать их в JavaScript.

Требования

Что такое синглтоны?

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

Исходя из этого определения, синглтоны кажутся очень похожими на глобальные переменные. Но синглтоны отличаются от глобальных переменных несколькими вещами:

  • Глобальные переменные имеют лексическую область видимости, а синглтоны – нет. Это значит, что если внутри блока есть глобальная переменная и еще одна переменная с тем же именем, то приоритет имеет первая ссылка. Однако для синглтонов не следует объявлять эту ссылку повторно.
  • Значение синглтона изменяется с помощью методов.
  • Синглтон не освобождается до завершения работы программы (что, как правило, не так для глобальных переменных).

Даже в языке, который поддерживает глобальные переменные, синглтоны могут быть очень полезны – в отдельных сценариях синглтоны работают лучше глобальных переменных. Синглтоны часто используются в объектах логирования или классах параметров конфигурации.

Объявление синглтонов

Существует несколько способов объявить синглтон. Вероятно, вы уже встречали вот такой формат:

var SingletonInstance = {

 method1: function () { ... }

 method2: function () { ... }

};

Такой синглон будет регистрироваться в консоли следующим образом:

console.log(SingletonInstance.method1());

console.log(SingletonInstance.method2());

Следует иметь в виду, что это не лучший формат объявления синглтона. Другой способ – использовать класс factory, который один раз создает синглтон.

var SingletonFactory = (function(){

  function SingletonClass() {

    // ...

  }

  var instance;

  return {

    getInstance: function(){

      if (!instance) {

        instance = new SingletonClass();

        delete instance.constructor;

      }

      return instance;

    }

  };

})();

Это лучшая альтернатива первому формату, потому что определение класса является частным, а конструктор удаляется после создания первого экземпляра. Это предотвратит создание в программе повторяющихся синглтонов. Недостатком этого подхода является то, что он очень похож на шаблон проектирования factory.

Есть еще третий подход. Он комбинирует классы ES6 и метод Object.freeze():

class Singleton {

  constructor() {

   // ...

  }

  method1() {

    // ...

  }

  method2() {

    // ...

  }

}

const singletonInstance = new Singleton();

Object.freeze(singletonInstance);

Метод Object.freeze() предотвращает изменение свойств и значений объекта. Таким образом, применяя Object.freeze() к singletonInstance, вы не сможете впоследствии изменить какие-либо его свойства или значения в своем коде.

Можно пойти дальше и записать этот синглтон как модуль и экспортировать его с помощью функции export:

export default singletonInstance;

Затем этот синглтон можно использовать в отдельном файле, импортировав его:

import mySingleton from './script.js';

mySingleton.method1();

Зная все три подхода к объявлению синглтонов, вы можете выбирать, какой метод лучше всего подходит для вашего конкретного случая использования и сохраняет при этом высокую читабельность кода.

Заключение

Синглтоны не всегда необходимы в коде JavaScript. Их следует использовать там, где это не повлияет на состояние приложения (эта особенность синглтонов сильно ограничивает их применение в больших приложениях).

Имея этот важный шаблон проектирования в своем инструментарии, вы можете изучить шаблоны factory в JavaScript.

Tags:

Добавить комментарий