Я ищу лучший шаблон для реализации что-то вроде этого:Настраиваемый перечисление в Java
public static enum Foo {
VAL1(new Bar()),
VAL2(new FooBar());
private final bar;
private Foo(IBar bar) {
this.bar = bar;
}
public IBar getBar() { return bar; }
}
Вопрос заключается в том, что доступ к enum
вызывает побочные эффекты. Скажем, Bar
открывает соединение с БД и тому подобное. Поэтому, даже если мне просто нужно VAL2
, я должен заплатить цену за установку VAL1
.
OTOH, значение bar
плотно связано с enum
. Это как статический атрибут, но enum
не имеет ленивой инициализации. Я мог бы сделать абстракцию Foo.getBar()
и использовать анонимные классы, но тогда мне придется платить за установку каждый раз.
Есть ли дешевый способ добавить ленивый init для атрибутов enum
s?
[EDIT] сделать это ясно:
getBar()
называется миллионы раз. Это должно быть ослепляющим быстро.Мы говорим о синглете здесь (точно так же, как и
enum
). Должен быть создан только один экземпляр.Для дополнительных целей, модульные тесты должны иметь возможность отменить это поведение.
Экземпляры должны создаваться лениво.
Одним из решений мы старались, чтобы зарегистрировать значения, как бобы весной:
<bean id="VAL1.bar" class="...." />
Это позволило нам определить значения во время выполнения и переопределить их в тестах. К сожалению, это означает, что мы должны ввести ApplicationContext
в enum
. Поэтому для этого нам нужна глобальная переменная. cringe
Что еще хуже: поиск значения в getBar()
слишком медленный. Мы можем synchronize
getBar()
и использовать if(bar!= null)bar=context.get(name()+".bar");
, чтобы решить эту проблему.
Но есть ли способ без этого, который так же безопасен и быстр, как и сами значения enum
?
ли они все должны быть в том же перечислении? Если вы используете разные перечисления, каждый будет загружать только одну (или одну группу) значений. –
Все они принадлежат к тому же перечислению. Распространение их по нескольким перечислениям не имеет смысла с логической/семитической точки зрения. –