Ответ
Singleton (Одиночка) — это порождающий шаблон проектирования, который гарантирует, что у класса существует только один экземпляр, и предоставляет глобальную точку доступа к этому экземпляру.
Зачем он нужен в Node.js?
В Node.js модули по умолчанию являются синглтонами (кэшируются после первого require). Однако паттерн полезен, когда нужно явно контролировать процесс создания единственного экземпляра класса, например, для управления подключением к базе данных, конфигурацией или логгером.
Классическая реализация в JavaScript (ES6+):
class DatabaseConnection {
constructor(config) {
if (DatabaseConnection.instance) {
return DatabaseConnection.instance;
}
// Имитация сложной инициализации подключения
this.connectionString = config.connectionString;
this.isConnected = false;
this.connect();
DatabaseConnection.instance = this;
}
connect() {
console.log(`Устанавливается подключение к ${this.connectionString}...`);
// Логика подключения...
this.isConnected = true;
}
query(sql) {
if (!this.isConnected) throw new Error('Нет подключения к БД');
console.log(`Выполняется запрос: ${sql}`);
// Логика выполнения запроса...
}
// Статический метод для удобного доступа (опционально)
static getInstance(config) {
if (!DatabaseConnection.instance) {
DatabaseConnection.instance = new DatabaseConnection(config);
}
return DatabaseConnection.instance;
}
}
// Использование
const config = { connectionString: 'postgresql://localhost/mydb' };
const db1 = new DatabaseConnection(config); // Создаст экземпляр
const db2 = new DatabaseConnection(config); // Вернет существующий экземпляр
const db3 = DatabaseConnection.getInstance(config); // Вернет тот же экземпляр через статический метод
console.log(db1 === db2 && db2 === db3); // true
Особенности в Node.js:
- Благодаря модульной системе, часто достаточно экспортировать один экземпляр из файла модуля:
// logger.js class Logger { /* ... */ } module.exports = new Logger(); // Все, кто require('./logger'), получат один экземпляр - В Node.js нет проблемы многопоточности, поэтому реализация проще, чем в Java/C#.
Недостатки:
- Усложняет модульное тестирование: Глобальное состояние может приводить к зависимостям между тестами. Решается использованием dependency injection.
- Скрывает зависимости: Класс, использующий синглтон, имеет скрытую зависимость, что нарушает принцип инверсии зависимостей.
Вывод: Используйте синглтон осознанно, в основном для истинно глобальных, неделимых ресурсов, и помните о его влиянии на тестируемость кода.
Видео-ответы
▶
▶
▶
▶
▶
▶
▶
▶
▶