Почему шаблон Singleton так распространён?

«Почему шаблон Singleton так распространён?» — вопрос из категории Паттерны, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Singleton распространён, потому что он решает конкретную задачу — гарантирует существование единственного экземпляра класса и предоставляет к нему глобальную точку доступа.

Ключевые причины популярности:

  1. Контроль над ресурсами: Идеален для дорогих или общих ресурсов, которые не должны дублироваться (например, подключение к базе данных, кэш, конфигурация, логгер).
  2. Глобальный доступ: Упрощает доступ к экземпляру из любой части приложения без необходимости передавать его через параметры.
  3. Ленивая инициализация (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.