Весной стартует сезон найма, успей отхватить свой оффер!

Паттерн Синглтон (Singleton, Одиночка)

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

Зачем нужен Синглтон:

Синглтон обеспечивает централизованный способ управления ресурсами и предоставляет универсальную «точку входа» (instance) к своему функционалу.
При этом он гарантирует, что более одного экземпляра объекта не будет создано в ходе выполнения программы.


Когда применять «Синглтон»?

1

Ограниченный ресурс

Когда нужно работать с ресурсом, который должен существовать строго в одном экземпляре, например глобальный логгер, пул соединений или конфигурация приложения.

2

Упрощение доступа

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

3

Замена глобальных переменных

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


Как работает Синглтон?

  1. Закрытый (private) конструктор
    Запрещает создавать объекты через new, вынуждая всех пользоваться специальным методом доступа.

  2. Статический метод доступа
    Обычно называется getInstance(). При первом вызове создаёт экземпляр и сохраняет его, а при последующих возвращает уже созданный объект.

  3. Статическая переменная
    Хранит ссылку на единственный экземпляр класса.


Пример (TypeScript)

class Singleton {
  private static instance: Singleton;
  private constructor() {
    // Приватный конструктор не даёт создать объекты извне
    console.log("Инициализация единственного экземпляра...");
  }

  public static getInstance(): Singleton {
    if (!Singleton.instance) {
      Singleton.instance = new Singleton();
    }
    return Singleton.instance;
  }

  public someMethod(): void {
    console.log("Вызов метода у синглтона!");
  }
}

// Пример использования
const obj1 = Singleton.getInstance(); // Инициализация и создание
const obj2 = Singleton.getInstance(); // Возвращает уже созданный экземпляр

console.log(obj1 === obj2); // true — оба ссылаются на один и тот же объект
obj1.someMethod(); // "Вызов метода у синглтона!"
  • instance — статическое свойство, в котором хранится ссылка на единственный объект.
  • constructor закрыт для внешнего вызова.
  • При вызове getInstance() метод проверяет, есть ли уже созданный объект. Если нет — создаёт, если да — возвращает существующий.

Преимущества

  • Единственная точка доступа: Удобно управлять объектом, который должен существовать в одном экземпляре.
  • Легче тестировать, чем глобальные переменные: Можно «подменять» Singleton в тестах, хотя это всё ещё не столь просто, как при обычной зависимости.
  • Отсутствие дублирования: Гарантируется, что объект не будет создан повторно.

Недостатки

  • Глобальное состояние: Синглтон фактически заменяет глобальные переменные, что при избыточном использовании может усложнить тестирование и логику приложения.
  • Сложнее рефакторить: Если для тестов или новых фич внезапно понадобится больше экземпляров, переделка из Синглтона может быть проблемной.
  • Неявные зависимости: Код, который использует Singleton, часто прямо не указывает в интерфейсе о зависимостях, а просто вызывает getInstance(), что может скрывать логику работы.

Внимание:

Избыточное использование синглтонов может привести к сильной связанности кода и затруднить тестирование. Перед тем, как внедрять Singleton, подумайте о паттернах вроде IoC (Inversion of Control) или DI (Dependency Injection).

Когда использовать

  • Уникальные ресурсы: Логгер, конфигурация системы, класс для работы с глобальным кэшем.
  • Синхронизация: Когда объект должен «управлять» ресурсом, доступным из разных потоков (если речь о бэкенде), а нужно гарантировать «одиночное» хранение.

Источник

Подробнее про Синглтон можно почитать здесь.