Создание Singleton с аргументами в Java: решение проблемы

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Чтобы создать синглтон с аргументами, предпочтительно применять подход с отложенной инициализацией с использованием внутреннего класса-холдера, где реализуется инкапсуляция параметров в конфигурационном объекте. Такой подход гарантирует корректное использование в многопоточной среде и инициализацию экземпляра с требуемыми аргументами в момент первого обращения.

Java
Скопировать код
public class SingletonConfig {
    private String value;

    public SingletonConfig(String value) {
        this.value = value;
    }
    // создадим геттер для value
}

public class MySingleton {

    private final SingletonConfig config;

    private MySingleton(SingletonConfig config) {
        this.config = config;
    }
    
    private static class Holder {
        private static MySingleton instance = new MySingleton(new SingletonConfig("значение по умолчанию"));
    }
    
    public static MySingleton getInstance(SingletonConfig config) {
        if (config != null) {
            Holder.instance = new MySingleton(config);
        }
        return Holder.instance;
    }
}

Класс SingletonConfig используется для передачи параметров при первичной инициализации синглтона. После его инициализации для получения экземпляра синглтона вызывайте getInstance(null).

Java
Скопировать код
SingletonConfig config = new SingletonConfig("значение параметра"); 
MySingleton singleton = MySingleton.getInstance(config);

Такой подход идеально подходит для конфигурации системы на старте. Однако некорректное использование параметров во время выполнения может нарушить логику работы синглтона.

Кинга Идем в IT: пошаговый план для смены профессии

Гарантия уникальности синглтона

Чтобы предотвратить возможность повторного создания синглтона с другими аргументами, в метод getInstance добавлена проверка:

Java
Скопировать код
public static MySingleton getInstance(SingletonConfig config) {
    if (Holder.instance.config != null && config != null) {
        throw new IllegalStateException("Изменение конфигурации невозможно после инициализации синглтона");
    }
    return Holder.instance;
}

Потокобезопасность и иммутабельность состояния

Соблюдение потокобезопасности и неизменяемости синглтона достигается за счёт использования final поля для хранения конфигурации, что предотвращает возможность изменения после инициализации объекта.

Применение паттерна Builder при создании синглтона

Если требуется создать синглтон с возможностью сложной инициализации, предлагается применить паттерн Builder, который позволяет контролировать процесс инициализации, а также предотвращает повторное создание уже инициализированного объекта.

Управление синглтонами с помощью паттерна Factory

Для управления множеством параметров синглтонов предлагается использовать паттерн Factory. Этот паттерн хранит экземпляры объектов и предотвращает их неразрешенное дублирование.

Использование перечислений для управления синглтонами

Enum можно использовать для управления ограниченным набором параметризованных синглтонов, обеспечивая уникальность каждого экземпляра и контроль его создания.

Визуализация

Схематически создание синглтона можно сравнить с процессом "лепки" снеговика, которому разрешается украшать только в момент первого "лепления":

Markdown
Скопировать код
Двор синглтонов: [⛄️] Доступные украшения: [🥕, 🧣]

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

Java
Скопировать код
Snowman.getInstance(🥕 /*новая морковка*/, 🧣 /*новый шарф*/); 
// К сожалению, снеговик остается таким, каким был.

Управление большими объектами через распределенное кэширование

Распределенные кэш-системы, такие как Hazelcast или Apache Ignite, рекомендуется использовать для больших и распределенных систем: они расширяют концепцию синглтона на пространство кластера.

Управление логированием с помощью синглтона

Паттерн синглтона нашел свое применение в системах логирования, где одного экземпляра журнала достаточно для всего приложения.

Предупреждение: конфликты синглтонов в разных JVM

Стоит помнить, что синглтон в одной JVM не связан с экземпляром в другой JVM. Для поддержания согласованного состояния между JVM требуется внешняя координация.

Полезные материалы

  1. Паттерн проектирования – Синглтон — Основные принципы реализации синглтона в Java.
  2. Проблемы с двойной проверкой блокировки — Распространенные ошибки в реализации синглтона.
  3. Синглтон – Wikipedia — Описание отложенной инициализации для синглтонов.
  4. DZone – Паттерн синглтон — Подробное описание синглтонов, включая реализацию с использованием Enum.
  5. Эффективные реализации синглтона в Java — Обсуждение эффективных способов реализации синглтона.
Свежие материалы