Коротка відповідь
middleSingleton — це патерн, що гарантує існування лише однієї інстанції класу і забезпечує глобальний доступ до неї. У TS це реалізується через приватний конструктор і статичне поле, що зберігає екземпляр: `class Logger{private static instance:Logger; private constructor(){...}static getInstance(){return this.instance|| (this.instance=new Logger());}}`
Повне пояснення
1. Що це і навіщо
Singleton — патерн створення, що обмежує кількість екземплярів класу до одного і надає глобальний доступ. У GoF розташований у секції "Creational"; застосовується, коли потрібен централізований ресурс (логер, конфігурація, пул з’єднань).
2. Принцип роботи / алгоритм
Клас має приватний конструктор, щоб заборонити зовнішнє створення. Статичне поле instance зберігає екземпляр; метод getInstance() повертає його, створюючи при першому виклику. Це гарантує однорідність і доступ з будь‑якого місця.
3. Реалізація (JS / TS)
- Базова реалізація
class Singleton {
private static instance: Singleton;
private constructor() {}
static getInstance(): Singleton {
if (!this.instance) this.instance = new Singleton();
return this.instance;
}
}
- Реалістичний приклад (логер)
class Logger {
private static instance: Logger;
private constructor() {}
static getInstance(): Logger {
if (!this.instance) this.instance = new Logger();
return this.instance;
}
log(msg: string) { console.log(`[${new Date().toISOString()}] ${msg}`); }
}
// Usage
Logger.getInstance().log('App started');
- Спрощений для новачка (конфіг)
class Config {
private static instance: Config;
public readonly apiUrl = 'https://api.example.com';
private constructor() {}
static getInstance(): Config {
return this.instance ?? (this.instance = new Config());
}
}
4. Тестування (Jest або Vitest)
test('Singleton returns same instance', () => {
const a = Logger.getInstance();
const b = Logger.getInstance();
expect(a).toBe(b);
});
5. Проблеми та edge cases
- Проблема багатопотоковості – у Node.js це не критично, але в браузері Web Workers потрібна синхронізація.
- Неправильне використання ролей – створення нового екземпляру через
newзамістьgetInstance(). - Зайва абстракція – Singleton часто використовується там, де можна просто експортувати об’єкт.
- Cyclical dependencies – якщо Singleton залежить від іншого модуля, що теж є Singleton, виникає цикл.
- Performance‑пастки – кожен виклик
getInstance()перевіряє стан, що додає мікросекунди; у критичних секціях можна кешувати.
6. Оптимізація та продуктивність
- Пам’ять: лише один об’єкт, тому мінімальний витрата.
- Швидкість: перевірка
if (!this.instance)– O(1). Якщо потрібна висока частота, можна зберегти посилання без перевірки. - Масштабованість: у розподілених системах Singleton не працює; треба використовувати зовнішній кеш або базу.
7. Без JS / архітектурні альтернативи
- HTML/CSS: глобальний стан можна зберігати в
localStorageабо у контексті React (Context API). - Архітектура без патерна: експортувати готовий об’єкт (
export const config = {...}) замість класу.
8. Cheatsheet + follow-up
- Cheatsheet: приватний конструктор → статичне поле
instance→ методgetInstance(). - Interview Q1: Як Singleton впливає на тестування? (відповідь: потребує моків або ін’єкції залежностей).
- Interview Q2: Які альтернативи Singleton у розподілених системах? (відповідь: Redis, ZooKeeper, конфігураційні сервери).