Является ли Single-Element Enum Type Singleton действительно широко принятой хорошей идеей?
Пункт 3 Josh Block Эффективная Java (Enforce Singleton Property с частным конструктором или Enumerator) упоминает, что "Хотя этот подход еще не принят, одноэлементный тип перечисления - лучший способ реализовать одноэлементный."
Пример:
public enum Elvis {
INSTANCE;
private final String[] favoriteSongs =
{ "Hound Dog", "Heartbreak Hotel" };
public void printFavorites() {
System.out.println(Arrays.toString(favoriteSongs));
}
}
Продолжение: "Этот подход функционально эквивалентен общедоступному полевому подходу, за исключением того, что он более краток, предоставляет бесплатную сериализующую технику и предоставляет надежную гарантию против множественного экземпляра даже в условиях сложных атак с сериализацией или отражением."
Самый большой недостаток, который я вижу, - это не перечисления, которые не должны иметь изменяемое состояние? Обычно используется Singleton с состоянием.
Итак, этот шаблон действительно стал более распространенным с даты публикации (второе издание опубликовано в 2008 году)?
Ответы
Ответ 1
В то время как перечисления обычно не изменяются, этот факт основан на предположениях о том, как будет использоваться перечисление. Хотя эти предположения обычно сохраняются, они не всегда, и один такой случай, когда они этого не делают, заключается в создании Singleton.
Хотя это не самое распространенное использование перечислений, вполне законно иметь перечисление с изменчивым состоянием, хотя вы можете указать этот факт в своем коде, чтобы любой другой программист, который мог бы смотреть на него, не получал запутался.
Что касается популярности этого шаблона дизайна, я видел его довольно часто, но не так много, что я бы сказал, что он стал "общим".
Ответ 2
(Этот ответ предполагает, что "принудительный" синглтон действительно то, что вы хотите, в отличие от де-факто синглтона, управляемого вашей инфраструктурой DI (например, Guice @Singleton
), что, вероятно, чаще всего является правильной идеей.)
Разложить свой вопрос на два: действительно ли он принят? Нет, не так широко, как должно быть. Это хорошая идея? Да!
Перечень Java - это класс, который может иметь только фиксированный набор из N экземпляров, которые жестко закодированы в источнике.
Singleton - это класс, который может иметь только фиксированный набор из N экземпляров, которые жестко закодированы в источнике. И N == 1.
Это так просто!
Ответ 3
Перечисления могут иметь изменяемое состояние. Обычно это не очень хорошая идея, потому что характер перечисления состоит в том, чтобы иметь точно X-версии типа Y, где X больше 1, поэтому жонглирование вокруг состояния (кроме использования полей/свойств) становится немного кошмаром, поскольку каждый метод необходимо учитывать все возможные состояния всех констант Xnum.
Но если вы все равно определите перечисление с одной константой; вы можете просто рассматривать эту единственную константу как обычный объект и делать все предположения, которые приходят с ней. IOW: проблема наличия X-версий состояния уходит, потому что X теперь 1.
Ответ 4
Нет enum
не должны иметь изменяемое состояние. Статика обычно не должна изменяться. Синглтоны - это просто способы обмануть изменчивую статику. (Объекты без состояния, которые реализуют интерфейс, - это другое дело.)
Ответ 5
Это не очень хорошая идея.
Это заставляет ваш класс наследовать от конкретного класса Enum
. Это загрязняет вашу иерархию типов.
Тип INSTANCE
должен быть точно Elvis
; это не может быть подтип Elvis
.
В более общем плане вы не можете свободно выбирать способ создания экземпляра.
И синтаксис-мудрый, действительно ли это слишком много набирает?
public class Elvis {
static public Elvis INSTANCE = new Elvis();