Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое паттерн Singleton
Singleton — это порождающий паттерн проектирования, который гарантирует, что класс имеет только один экземпляр и предоставляет глобальную точку доступа к этому экземпляру. Паттерн решает две основные задачи: ограничивает создание экземпляра класса одним объектом и предоставляет удобный доступ к этому объекту из любого места в приложении.
Основная идея
Паттерн Singleton особенно полезен в следующих случаях:
- Централизованное управление ресурсами: логирование, конфигурация, пулы соединений
- Предотвращение дублирования: база данных, кэш, состояние приложения
- Синхронизация: единая точка для управления состоянием
Реализация в JavaScript
Классический подход с использованием класса
class Logger {
constructor() {
if (Logger.instance) {
return Logger.instance;
}
this.logs = [];
Logger.instance = this;
}
log(message) {
this.logs.push(message);
console.log(message);
}
getLogs() {
return this.logs;
}
}
const logger1 = new Logger();
const logger2 = new Logger();
console.log(logger1 === logger2); // true — один и тот же объект
logger1.log('Hello');
console.log(logger2.getLogs()); // ['Hello']
Статический метод getInstance()
Более явный и контролируемый подход:
class Database {
constructor() {
this.connection = null;
}
static getInstance() {
if (!Database.instance) {
Database.instance = new Database();
Database.instance.connection = 'Connected to DB';
}
return Database.instance;
}
query(sql) {
return `Executing: ${sql}`;
}
}
const db1 = Database.getInstance();
const db2 = Database.getInstance();
console.log(db1 === db2); // true
console.log(db1.query('SELECT *')); // Executing: SELECT *
Объект-модуль (IIFE)
В JavaScript очень популярен подход с Immediately Invoked Function Expression:
const AppConfig = (() => {
let instance;
function createInstance() {
return {
apiUrl: 'https://api.example.com',
timeout: 5000,
debug: true,
getApiUrl() {
return this.apiUrl;
}
};
}
return {
getInstance() {
if (!instance) {
instance = createInstance();
}
return instance;
}
};
})();
const config1 = AppConfig.getInstance();
const config2 = AppConfig.getInstance();
console.log(config1 === config2); // true
console.log(config1.getApiUrl()); // https://api.example.com
Практические примеры в современном фронтенде
Глобальный Store в React
// store.js
class AppStore {
constructor() {
this.state = {};
this.listeners = [];
}
subscribe(callback) {
this.listeners.push(callback);
}
setState(newState) {
this.state = { ...this.state, ...newState };
this.listeners.forEach(listener => listener(this.state));
}
static getInstance() {
if (!AppStore.instance) {
AppStore.instance = new AppStore();
}
return AppStore.instance;
}
}
export default AppStore.getInstance();
Кэширование API запросов
class ApiCache {
constructor() {
this.cache = new Map();
}
set(key, value) {
this.cache.set(key, value);
}
get(key) {
return this.cache.get(key);
}
static getInstance() {
if (!ApiCache.instance) {
ApiCache.instance = new ApiCache();
}
return ApiCache.instance;
}
}
const cache = ApiCache.getInstance();
cache.set('user:1', { id: 1, name: 'John' });
console.log(cache.get('user:1')); // { id: 1, name: 'John' }
Плюсы и минусы
Плюсы
- Единственный экземпляр: гарантирует наличие только одного объекта
- Глобальная точка доступа: удобство использования из любого места
- Ленивая инициализация: объект создается при первом обращении
- Безопасное управление ресурсами: контроль над инициализацией
Минусы
- Скрытые зависимости: сложнее отследить, откуда берется объект
- Сложность тестирования: нужно мокировать глобальное состояние
- Нарушение SOLID: нарушает принцип единственной ответственности
- Глобальное состояние: может привести к проблемам в многопоточности
Альтернативы
В современном JavaScript часто используют модули и зависимости вместо Singleton:
// Вместо Singleton — просто модуль
const userService = {
getUser(id) {
return fetch(`/api/users/${id}`).then(r => r.json());
}
};
export default userService;
Итоги
- Singleton гарантирует единственный экземпляр класса
- В JavaScript реализуется через классы, методы или IIFE
- Полезен для конфигурации, логирования, кэширования
- Имеет как преимущества, так и недостатки
- Современная альтернатива — ES6 модули и зависимости