Перейти к содержанию

Одиночка (Singleton)

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

Опора на ООП

Singleton опирается на инкапсуляцию: паттерн прячет управление жизненным циклом и единственную точку доступа к экземпляру. Полиморфизм здесь обычно не является основной опорой.

Что показывает пример на 1С

  • CommonModules.Users.CurrentUser() возвращает SessionParameters.CurrentUser.
  • В мире 1С это чаще выглядит не как классический объект-одиночка, а как общий сервис-доступ к уникальному для сеанса состоянию.
  • Условно stateless singleton в 1С можно увидеть в общем модуле: у него нет собственного экземпляра с управляемым жизненным циклом, но есть единая точка входа в логику.
  • Платформенный пример более "настоящего" singleton-подобного объекта - глобальный объект Metadata, который уже предоставлен платформой и используется как единая точка доступа к метаданным.
  • Такой пример полезен именно как архитектурная оговорка: в 1С паттерн часто проявляется через общие модули, глобальные объекты платформы и параметры сеанса, а не через конструкторы классов.

Пример

Function CurrentUser() Export

    SetPrivilegedMode(True);
    Return SessionParameters.CurrentUser;

EndFunction
ProductsMetadata = Metadata.Catalogs.Products;
ProductAttributes = ProductsMetadata.Attributes;

Вариации singleton в 1С

В 1С почти всегда нужно сначала договориться, в каком именно масштабе объект должен быть "одним".

  • Singleton уровня бизнеса: например, текущая учетная политика, активный релиз обмена или единственный набор правил, который в предметной области должен существовать в одном экземпляре.
  • Singleton уровня сеанса: текущий пользователь, параметры сеанса, технический контекст конкретного подключения.
  • Singleton уровня процесса: объект или кэш, живущий только внутри одного рабочего процесса rphost.
  • Singleton уровня приложения в целом: единый экземпляр для всей информационной базы или всего кластера.

Проблема в том, что это четыре очень разные трактовки "одиночки". Без такой оговорки слово Singleton в 1С слишком легко вводит в заблуждение.

Особенность платформы

С практической точки зрения собственный строгий singleton в прикладном коде 1С обычно не создать.

Причина в архитектуре платформы: в клиент-серверном варианте кластер серверов состоит из одного или нескольких рабочих процессов, а серверный код выполняется внутри rphost (архитектура кластера). Платформа распределяет клиентские соединения по рабочим процессам кластера.

Из этого следует важное ограничение:

  • даже если вы где-то закешировали "единственный экземпляр" в серверной памяти;
  • это будет singleton максимум уровня конкретного рабочего процесса;
  • но не всего приложения и не всего кластера.

То есть архитектурно вы не контролируете единый глобальный процесс, в котором исполняется весь код. В многопроцессной схеме нельзя просто объявить объект и считать, что он единственный "на всю систему".

Поэтому в 1С чаще встречаются такие практические варианты:

  • общий модуль как stateless singleton, то есть единая точка входа без собственного состояния экземпляра;
  • SessionParameters как singleton уровня сеанса;
  • Metadata как платформенный глобальный объект, который уже дан средой выполнения;
  • отдельные данные в базе как "бизнес-singelton", если уникальность гарантируется не памятью процесса, а моделью данных.

Для Metadata это особенно наглядно: разработчик не создает его вручную, а получает от платформы готовую единую точку доступа к метаданным. Это прямо видно и в официальных рекомендациях по получению метаданных, где используется глобальный объект Metadata и его методы (1C:DN).

Где полезен в 1С

  • для доступа к состоянию сеанса;
  • для инфраструктурных сервисов, которые действительно должны быть единственными в контексте приложения;
  • как единая точка чтения технического контекста.

Когда паттерн лишний

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

Источник примера