Как на практике реализовать Singleton через enum от Joshua Bloch’а?

331
24 июля 2017, 13:31

Есть относительно известная реализация шаблона Singleton от Joshua Bloch’а которая часто иллюстрируется вот в таком виде:

public enum Singleton {
    INSTANCE;
}

Я решил реализовать ее в реальном коде и столкнулся с некоторым непониманием. Вот общая картина: Есть DAO слой который и должен воплощать упомянутый выше шаблон:

public class TaskDAO implements DAO<Integer, Task> {
    private final AtomicReference<SessionFactory> factory;
    public TaskDAO(final AtomicReference<SessionFactory> factory) {
        this.factory = factory;
    }
    ... CRUD методы ...
}

Вопрос в том как мне использовать enum если я хочу при создании инстанса использовать динамическую инъекцию зависимостей?

Сомневаюсь что Joshua Bloch этого не учел...

Или сам паттерн исключает использование конструктора? (Хотя странно если его главная задача гарантировать что экземпляр будет только один, то не понятно как внедрение зависимостей через конструктор может противоречить этой идее... Или противоречит?).

Если подитожить все выше сказанное в виде вопроса на который который можно дать конкретный ответ: Идея шаблона синглтон противоречит внедрению зависимостей через конструктор, или только версия Joshua Bloch'a?

Answer 1

Сама концепция Singleton противоречит принципу Dependency Injection.

Проблема с Singleton состоит в том, что они представляют собой глобальное состояние, которое трудно предсказать, особенно в тестах.

Имейте в виду, что объект может быть по факту Singleton, но доступ к нему все равно можно получить через Dependency Injection.

В свое время тоже озадачивался таким вопросом, и сохранил себе в Evernotes статью, принципы из которой использую уже больше года =) Вот перевод:

Важно поддерживать баланс между зависимостями, представленными как синглтоны и те, которые вводятся с использованием принципов Dependency Injection. Надеюсь следующие подсказки помогут вам определить, какой шаблон использовать:

  • Если зависимость является "глобальной", то есть она используется многими классами и / или несколькими слоями, используйте Singleton.
  • В противном случае добавьте его в зависимые классы, используя шаблон Dependency Injection.

READ ALSO
Как хранить корзину на сайте?

Как хранить корзину на сайте?

Здравствуйте, назрел вопросКак вы думайте, как лучше всего реализовать корзину интернет магазина

401
Внедрить в openfire свою бд

Внедрить в openfire свою бд

Подскажите, пожалуйста, можно ли в openfire работать со своей бд?

231
Release сборка Chromium

Release сборка Chromium

Пробую собрать Chromium по инструкцииНо всегда получаю debug сборку

234
Не могу подключить mockito

Не могу подключить mockito

Требуются заглушки для юнит тестовУстановил Mockito импортировал в библиотеки в проект

490