Синглтон (Традиционный против Enum)
Отказ от ответственности: извинения, если этот вопрос является слишком основным.
Я изучаю Синглтон и быстро задаю вопрос о его реализации. Являются ли эти различия чисто предпочтениями в кодировании или я что-то упустил?
Синглтон Класс
public enum SerialNumberGen {
INSTANCE;
private int count;
public synchronized int getNextSerial(){
return count++;
}
Пример реализации
.println(SerialNumberGenerator.INSTANCE.getNextSerial());
Моя реализация
SerialNumberGen gen = SerialNumberGen.INSTANCE;
System.out.println(gen.getNextSerial());
Моя реализация все еще придерживается шаблона Singleton? Или это то, на что должны ссылаться классы Enum.
Благодарю.
2 ответа
Моя реализация все еще придерживается шаблона Singleton?
Да. У вас все еще есть ровно один экземпляр SerialNumberGen
,
Нет никакой разницы между ними, кроме дополнительной переменной во втором случае.
Вы должны тщательно подумать о том, чтобы иметь изменчивый enum
, Мнение команды Java-библиотек Google:
Статическое состояние опасно для начала, но гораздо хуже для перечислений. Мы все думаем о значениях перечисления как о константах - и даже называем их "константами перечисления" - и были бы очень удивлены, если какое-либо из их состояний когда-либо изменилось или не было поточно-ориентированным.
Хотя перечисления являются удобным способом создания потоковых синглетонов, они не обязательно хорошо подходят для того, что вы здесь делаете.
Для меня главный вопрос здесь: почему вы думаете, что вам нужен синглтон? Я предлагаю вам прочитать и тщательно обдумать, что же такого плохого в синглетах?,
Здесь нет ничего, что действительно требует синглтона. Вы можете просто иметь один экземпляр SerialNumberGen
, который вы вводили везде, где это нужно.
It is still a singleton.
But please note: the much better approach is to encapsulate the specific behavior into an interface, so that
public enum ServiceProvider implements Service {
так что вы можете сделать
Service service = ServiceProvider.INSTANCE
например. И иду оттуда; Я даже создаю обычный
class ServiceImpl implements Service {
а затем сделать
public enum ServiceProvider implements Service {
INSTANCE;
private final Service delegate = new ServiceImpl()
поскольку это помогает дополнительно разделить обязанности
- предоставление этого интерфейса службы
- предоставление синглтона
И это также помогает при написании модульных тестов.