Что такое Singleton и какие у него проблемы?
Порождающие паттерны
Singleton гарантирует, что у класса существует один экземпляр, и даёт глобальную точку доступа к нему; расплата — скрытые зависимости, сложности с тестами и многопоточностью.
Как выглядит
class Config {
static #instance = null;
static get() {
Config.#instance ??= new Config();
return Config.#instance;
}
}В многопоточных языках ленивую инициализацию защищают двойной проверкой с блокировкой или делают eager.
Проблемы
- Глобальное состояние: зависимость не видна в сигнатуре, класс тянет синглтон неявно.
- Тестирование: состояние протекает между тестами, подменить сложно.
- Нарушение SRP: класс и работает, и контролирует собственное количество.
- В кластере из нескольких процессов «один экземпляр» всё равно не гарантирован.
Что вместо
Один экземпляр создают в composition root и передают через внедрение зависимостей — единственность становится решением конфигурации, а не класса.
Когда допустим
Логгеры, пулы соединений, stateless-сервисы — то, что действительно едино и не мутирует.
Коротко для собеседования
Singleton ограничивает класс одним экземпляром и отдаёт его через статический метод, но по сути это глобальная переменная с красивым названием. На практике единственность лучше обеспечить в composition root и передавать объект через DI — так зависимость видна и легко подменяется в тестах.