根据选定的枚举值调用对象的特定方法
Call specific method on object depending on selected enum value
假设我们有一个代表可搜索字段的枚举:
enum SearchableFields {
ALL,
FIELD1,
FIELD2,
FIELD3;
}
此枚举通过 GUI 内的(组合框)选择显示。在运行时,我想评估这个组合框的选择并进行相应的搜索。
根据选择,我需要通过 getter.
从 POJO(下面的示例)中检索要搜索的字段
class FieldPojo {
private String field1;
private String field2;
private String field3;
...
public String getField1() {
return field1;
}
...
}
我目前使用 switch
语句来评估 SelectableFields
的选择,然后检索要搜索的正确字段:
private String retrieveField(FieldPojo f) {
switch (selectedField) {
case ALL:
return retrieveAll(); // method that retrieves all available fields
case FIELD1:
return f.getField1();
...
}
这确实有效,但我觉得它很笨重。
问题:
有没有更简洁的方法来做到这一点而无需通过 switch
评估 enum
? (Java 8)
枚举可以包含方法定义,因此一种方法是根据枚举值定义检索字段名的方法。我假设您也将实际字段名称存储为成员字段。然后你可以覆盖特殊 ALL
值的方法:
enum SearchableFields {
ALL("all") { // all is just a placeholder in this case
@Override
String retrieveField(FieldPojo f) {
// logic for all fields
}
},
FIELD1("field1"),
FIELD2("field2"),
FIELD3("field3");
SearchableFields(String fieldName) {
this.fieldName = Optional.of(fieldName);
}
SearchableFields() {
fieldName = Optional.empty();
}
private final Optional<String> fieldName;
String retrieveField(FieldPojo f) {
if (fieldName.isPresent()) {
return (String) f.getClass().getField(fieldName.get()).get(f);
} else {
// ...
}
}
}
您可以创建静态地图而不是 switch-case。
private static final Map<SearchableFields,Supplier<String>> searchableFieldsToFieldPojo = Map.of(
ALL, this::retrieveAll,
FIELD1, FieldPojo::retrieveAll
);
然后您可以通过以下方式访问:
searchableFieldsToFieldPojo.get(selectedField).get();
鉴于您可以修改代码的所有部分,您有多种选择:
- 将
retrieveField
放入 class FieldPojo
并修改其参数,使其以枚举 SearchableFields
作为参数。
- 将
FieldPojo
的字段作为值放入具有类型 SearchableFields
键的映射中。然后您可以决定是否要将“ALL”作为映射的额外条目,或者在类似于 retrieveField
的方法中将其作为特殊情况处理。如果你想更新枚举而不是 FieldPojo
class. ,你可以使用它来进行“默认”处理
- 您将
retrieveField
与 SearchableFields
枚举一起放入 class FieldPojo
- 因为只有 FieldPojo
知道,它实际提供哪些字段可搜索字段。
- 您使用内省来收集可能的可搜索字段列表并访问它们的内容。
根据您的实际要求(您只展示了它们的非常抽象和具体的版本),一种或另一种方法可能是适合您的“正确方法”。我实际上更喜欢“一切都变成 FieldPojo
”作为最强大的,但另一方面,如果你不能改变 FieldPojo
并且必须处理许多不同的 classes它,内省变体可能是正确的。 (请注意,它在安全方面很脆弱,而且可能非常慢。)
您可以在枚举常量中存储对 getter 的引用:
enum SearchableFields {
ALL(FieldPojo::retrieveAll),
FIELD1(FieldPojo::getField1)
private final Function<FieldPojo, String> accessor;
SearchableFields(Function<FieldPojo, String> acccessor) {
this.accessor = accessor;
}
public String get(FieldPojo fp) {
return accessor.apply(fp);
}
}
假设我们有一个代表可搜索字段的枚举:
enum SearchableFields {
ALL,
FIELD1,
FIELD2,
FIELD3;
}
此枚举通过 GUI 内的(组合框)选择显示。在运行时,我想评估这个组合框的选择并进行相应的搜索。
根据选择,我需要通过 getter.
从 POJO(下面的示例)中检索要搜索的字段class FieldPojo {
private String field1;
private String field2;
private String field3;
...
public String getField1() {
return field1;
}
...
}
我目前使用 switch
语句来评估 SelectableFields
的选择,然后检索要搜索的正确字段:
private String retrieveField(FieldPojo f) {
switch (selectedField) {
case ALL:
return retrieveAll(); // method that retrieves all available fields
case FIELD1:
return f.getField1();
...
}
这确实有效,但我觉得它很笨重。
问题:
有没有更简洁的方法来做到这一点而无需通过 switch
评估 enum
? (Java 8)
枚举可以包含方法定义,因此一种方法是根据枚举值定义检索字段名的方法。我假设您也将实际字段名称存储为成员字段。然后你可以覆盖特殊 ALL
值的方法:
enum SearchableFields {
ALL("all") { // all is just a placeholder in this case
@Override
String retrieveField(FieldPojo f) {
// logic for all fields
}
},
FIELD1("field1"),
FIELD2("field2"),
FIELD3("field3");
SearchableFields(String fieldName) {
this.fieldName = Optional.of(fieldName);
}
SearchableFields() {
fieldName = Optional.empty();
}
private final Optional<String> fieldName;
String retrieveField(FieldPojo f) {
if (fieldName.isPresent()) {
return (String) f.getClass().getField(fieldName.get()).get(f);
} else {
// ...
}
}
}
您可以创建静态地图而不是 switch-case。
private static final Map<SearchableFields,Supplier<String>> searchableFieldsToFieldPojo = Map.of(
ALL, this::retrieveAll,
FIELD1, FieldPojo::retrieveAll
);
然后您可以通过以下方式访问:
searchableFieldsToFieldPojo.get(selectedField).get();
鉴于您可以修改代码的所有部分,您有多种选择:
- 将
retrieveField
放入 classFieldPojo
并修改其参数,使其以枚举SearchableFields
作为参数。 - 将
FieldPojo
的字段作为值放入具有类型SearchableFields
键的映射中。然后您可以决定是否要将“ALL”作为映射的额外条目,或者在类似于retrieveField
的方法中将其作为特殊情况处理。如果你想更新枚举而不是FieldPojo
class. ,你可以使用它来进行“默认”处理
- 您将
retrieveField
与SearchableFields
枚举一起放入 classFieldPojo
- 因为只有FieldPojo
知道,它实际提供哪些字段可搜索字段。 - 您使用内省来收集可能的可搜索字段列表并访问它们的内容。
根据您的实际要求(您只展示了它们的非常抽象和具体的版本),一种或另一种方法可能是适合您的“正确方法”。我实际上更喜欢“一切都变成 FieldPojo
”作为最强大的,但另一方面,如果你不能改变 FieldPojo
并且必须处理许多不同的 classes它,内省变体可能是正确的。 (请注意,它在安全方面很脆弱,而且可能非常慢。)
您可以在枚举常量中存储对 getter 的引用:
enum SearchableFields {
ALL(FieldPojo::retrieveAll),
FIELD1(FieldPojo::getField1)
private final Function<FieldPojo, String> accessor;
SearchableFields(Function<FieldPojo, String> acccessor) {
this.accessor = accessor;
}
public String get(FieldPojo fp) {
return accessor.apply(fp);
}
}