Является ли Singleton паттерном или антипаттерном проектирования?

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

Ответ

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 становится антипаттерном:

  1. Нарушает принцип единственной ответственности (SRP) — совмещает управление жизненным циклом и бизнес-логику
  2. Усложняет тестирование — создает скрытые зависимости между компонентами
  3. Нарушает инкапсуляцию — предоставляет глобальное состояние
  4. Проблемы в многопоточных средах при некорректной реализации

Современные альтернативы:

  • Dependency Injection (Spring, Guice) — управление жизненным циклом через контейнер
  • Моносостояние (Monostate) — все экземпляры разделяют одно состояние
  • Контекст приложения — передача зависимостей через параметры

Вывод: Singleton остается валидным паттерном для ограниченного круга задач, но в современных приложениях предпочтительнее использовать внедрение зависимостей.