Я постараюсь быть кратким. Я пытаюсь сделать что-то вроде этого:
public enum Fruit {
APPLE("Apple", appleHelper::doAppleThing),
ORANGE("Orange", orangeHelper::doOrangeThing);
private String name;
private Function<String, List<T>> fruitFunction;
Fruit(String name, Function<String, List<T>> fruitFunction) {
this.name = name;
this.fruitFunction = fruitFunction;
}
public String getName() {
return name;
}
public <T> List<T> applyFruitFunction(String someString) {
return fruitFunction.apply(someString);
}
}
Так что позже у меня может быть такой метод, как
private <T> List<T> doFruitThing(String someString, Fruit fruit) {
List<T> transformedFruits = fruit.applyFruitFunction(someString);
if (transformedFruits.isEmpty()) {
throw new FruitException("There was no fruit of type " + fruit.getName());
}
return transformedFruits;
}
Я столкнулся с двумя проблемами.
doAppleThing и doOrangeThing не являются статическими методами и в идеале останутся такими, и я не могу найти никакого способа создать локальный экземпляр appleHelper и orangeHelper, чтобы справочник по методам работал.Function<String, List<T>> fruitFunction в качестве поля.Как это можно сделать? Или лучше подойти к этому?
может быть связано: stackoverflow.com/questions/8657608/…
может быть связано: stackoverflow.com/questions/22588518/…




Значения Enum могут иметь собственные реализации методов. Я бы написал это так:
public enum Fruit {
APPLE("Apple") {
private final AppleHelper helper = new AppleHelper();
@Override
public <T> List<T> applyFruitFunction(String someString) {
return helper.doAppleThing(someString);
}
},
ORANGE("Orange") {
private final OrangeHelper helper = new OrangeHelper();
@Override
public <T> List<T> applyFruitFunction(String someString) {
return helper.doOrangeThing(someString);
}
};
private String name;
Fruit(String name) {
this.name = name;
}
public String getName() {
return name;
}
public abstract <T> List<T> applyFruitFunction(String someString);
}
Однако, если вы дойдете до того, что вам потребуется состояние для каждого экземпляра для экземпляров перечисления, то, что у вас есть, будет все меньше и меньше перечислением и в большей степени просто абстрактным базовым классом. Возможно, было бы лучше изучить более объектно-ориентированный подход, используя, например, шаблон фабрика / маховик, а не привязываться к чистому перечислению для такого рода вещей. (Трудно сказать наверняка, потому что код в вопросе, очевидно, является просто упрощенным примером.)
Вот и решение! А также исправляет неуместный конструктор.
Это отличный ответ! Спасибо. Однако, поскольку реализация doAppleThing и doOrangeThing довольно сложна, я хочу, чтобы они принадлежали к другому классу (AppleHelper и OrangeHelper). Сделав эти методы статическими, я могу просто вызвать, но, полагаю, все еще нет способа сделать это с помощью методов экземпляра. Ну что ж, спасибо!
@EaterOfFromage: см. Мое последнее изменение - я считаю, что это то, что вы ищете.
Вы хотите, чтобы методы были нестатическими, но инициализировали перечисление экземпляром метода? А метод не может быть установлен извне перечисления? Именно для этого и нужны статические методы. Если, с другой стороны, вы хотите, чтобы перечисление принимало экземпляры своего вспомогательного класса и использовало методы этих экземпляров, то это именно то, для чего перечисления не предназначены.