Ответ
Singleton распространён, потому что он решает конкретную задачу — гарантирует существование единственного экземпляра класса и предоставляет к нему глобальную точку доступа.
Ключевые причины популярности:
- Контроль над ресурсами: Идеален для дорогих или общих ресурсов, которые не должны дублироваться (например, подключение к базе данных, кэш, конфигурация, логгер).
- Глобальный доступ: Упрощает доступ к экземпляру из любой части приложения без необходимости передавать его через параметры.
- Ленивая инициализация (Lazy Initialization): Экземпляр создаётся только при первом обращении, что может улучшить время старта приложения.
Пример потокобезопасной реализации в Java:
public class DatabaseConnection {
private static volatile DatabaseConnection instance;
private Connection connection;
private DatabaseConnection() {
// Инициализация подключения
}
public static DatabaseConnection getInstance() {
if (instance == null) { // Первая проверка (для производительности)
synchronized (DatabaseConnection.class) {
if (instance == null) { // Вторая проверка (для корректности)
instance = new DatabaseConnection();
}
}
}
return instance;
}
}
Критика и риски:
- Нарушает принцип единой ответственности (SRP): Класс управляет и своим жизненным циклом, и бизнес-логикой.
- Усложняет тестирование: Глобальное состояние затрудняет изоляцию тестов.
- Скрытые зависимости: Делает зависимости неявными.
Современная альтернатива: Вместо чистого Singleton в Spring-приложениях часто используют бины со scope="singleton", жизненным циклом которых управляет контейнер IoC.