Сколько ответственностей (по SRP) у паттерна Singleton?

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

Ответ

Классическая реализация паттерна Singleton нарушает принцип единственной ответственности (Single Responsibility Principle, SRP), так как сочетает в себе две ответственности:

  1. Управление жизненным циклом собственного экземпляра (гарантия существования не более одного объекта и контроль точки доступа к нему).
  2. Выполнение основной бизнес-логики, для которой класс был создан.

Пример нарушения SRP:

public class DatabaseConnection {
    // Ответственность 1: Управление экземпляром
    private static DatabaseConnection instance;
    private DatabaseConnection() {}
    public static DatabaseConnection getInstance() {
        if (instance == null) {
            instance = new DatabaseConnection();
        }
        return instance;
    }

    // Ответственность 2: Основная бизнес-логика
    public void connect() { /* ... */ }
    public void executeQuery(String query) { /* ... */ }
}

Как улучшить (следовать SRP):

  • Вынести управление экземпляром во внешний компонент (например, использовать Dependency Injection Container).
  • Сделать класс DatabaseConnection обычным классом, а контроль за количеством его экземпляров возложить на контейнер внедрения зависимостей. Это упрощает тестирование и делает систему более гибкой.