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