Подтвердить что ты не робот

Является ли 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 году)?

4b9b3361

Ответ 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();