Какой самый распространенный паттерн проектирования в Java?

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

Ответ

Один из самых распространенных — Singleton (Одиночка). Он гарантирует существование только одного экземпляра класса и предоставляет глобальную точку доступа к нему.

Типичное применение: Логгеры, конфигурации, пулы соединений, кэши.

Базовая реализация (ленивая, но не потокобезопасная):

public class Singleton {
    private static Singleton instance;
    private Singleton() {} // Приватный конструктор

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton(); // Проблема при многопоточности
        }
        return instance;
    }
}

Потокобезопасные реализации:

  1. synchronized метод (просто, но медленно):
    public static synchronized Singleton getInstance() { ... }
  2. Double-Checked Locking (оптимизировано):
    public class Singleton {
        private static volatile Singleton instance;
        private Singleton() {}
        public static Singleton getInstance() {
            if (instance == null) {
                synchronized (Singleton.class) {
                    if (instance == null) {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }
  3. Через enum (рекомендовано Джошуа Блохом, потокобезопасно и сериализуемо):
    public enum Singleton {
        INSTANCE;
        public void doSomething() { ... }
    }
    // Использование: Singleton.INSTANCE.doSomething();

Почему enum — лучший выбор? JVM гарантирует единственность экземпляра, автоматически обрабатывает сериализацию и защищает от рефлексивных атак.