Ответ
Singleton — это паттерн проектирования, но при неправильном использовании он может проявлять характеристики антипаттерна.
Паттерн Singleton (каноническая реализация):
public class Singleton {
private static volatile Singleton instance;
private Singleton() {
// Защита от рефлексии
if (instance != null) {
throw new RuntimeException("Use getInstance() method");
}
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
Когда Singleton — паттерн (правильное применение):
- Управление подключением к базе данных (пул соединений)
- Логгеры (если требуется глобальный доступ)
- Кэши конфигурации приложения
- Фабрики, которые должны быть единственными в системе
Когда Singleton становится антипаттерном:
- Нарушает принцип единственной ответственности (SRP) — совмещает управление жизненным циклом и бизнес-логику
- Усложняет тестирование — создает скрытые зависимости между компонентами
- Нарушает инкапсуляцию — предоставляет глобальное состояние
- Проблемы в многопоточных средах при некорректной реализации
Современные альтернативы:
- Dependency Injection (Spring, Guice) — управление жизненным циклом через контейнер
- Моносостояние (Monostate) — все экземпляры разделяют одно состояние
- Контекст приложения — передача зависимостей через параметры
Вывод: Singleton остается валидным паттерном для ограниченного круга задач, но в современных приложениях предпочтительнее использовать внедрение зависимостей.