Паттерн Синглтон (Singleton, Одиночка)
Синглтон (Singleton, Одиночка) — это порождающий паттерн проектирования, который гарантирует, что у класса будет только один единственный экземпляр, к которому можно получить доступ из любого места программы. Это особенно полезно для ресурсов, которые должны быть уникальны в рамках приложения: конфигурация, логгер, кэш и т.д.
Зачем нужен Синглтон:
Синглтон обеспечивает централизованный способ управления ресурсами и предоставляет универсальную «точку входа» (instance) к своему функционалу.
При этом он гарантирует, что более одного экземпляра объекта не будет создано в ходе выполнения программы.
Когда применять «Синглтон»?
Ограниченный ресурс
Когда нужно работать с ресурсом, который должен существовать строго в одном экземпляре, например глобальный логгер, пул соединений или конфигурация приложения.
Упрощение доступа
Когда нужно обеспечить удобную точку доступа к объекту из разных частей кода, без необходимости пробрасывать его через все уровни.
Замена глобальных переменных
Синглтон часто рассматривают как «более управляемую» альтернативу глобальным переменным, так как его можно протестировать и инкапсулировать логику.
Как работает Синглтон?
-
Закрытый (private) конструктор
Запрещает создавать объекты черезnew
, вынуждая всех пользоваться специальным методом доступа. -
Статический метод доступа
Обычно называетсяgetInstance()
. При первом вызове создаёт экземпляр и сохраняет его, а при последующих возвращает уже созданный объект. -
Статическая переменная
Хранит ссылку на единственный экземпляр класса.
Пример (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).
Когда использовать
- Уникальные ресурсы: Логгер, конфигурация системы, класс для работы с глобальным кэшем.
- Синхронизация: Когда объект должен «управлять» ресурсом, доступным из разных потоков (если речь о бэкенде), а нужно гарантировать «одиночное» хранение.
Источник
Подробнее про Синглтон можно почитать здесь.