如何从FieldType直接创建Elasticsearch Property对象?
这确实是个挺闹心的问题——硬写二十多个if-else分支不仅代码冗余,以后Elasticsearch出了新类型,还得回头改这块逻辑,完全不满足开闭原则。我给你两个更优雅的解决方案:
方案1:用函数式映射表(适用于无法修改FieldType的情况)
如果FieldType是Elasticsearch客户端自带的枚举(没法修改源码),咱们可以用一个Map把每个FieldType和对应的Property构建逻辑绑定起来,把分支逻辑转换成配置式的映射:
// 提前初始化好类型到构建函数的映射 private static final Map<FieldType, Function<Property.Builder, Property>> TYPE_PROPERTY_MAPPER = Map.of( FieldType.Keyword, builder -> builder.keyword(k -> k), FieldType.Boolean, builder -> builder.boolean_(b -> b), FieldType.Integer, builder -> builder.integer(i -> i), FieldType.Text, builder -> builder.text(t -> t), // 剩下的类型依次往这里加就行 ); public Property type2prop(FieldType type) { // 从映射表中取出对应的构建函数 Function<Property.Builder, Property> builderFunc = TYPE_PROPERTY_MAPPER.get(type); if (builderFunc == null) { // 处理未知类型,比如抛异常或者返回默认的Property throw new IllegalArgumentException("Unsupported FieldType: " + type.name()); } return Property.of(builderFunc); }
以后新增类型的时候,只需要在TYPE_PROPERTY_MAPPER里加一行键值对就行,完全不用碰原来的方法逻辑,维护起来省心多了。
方案2:给枚举添加抽象方法(适用于自定义FieldType的情况)
如果这个FieldType是你自己项目里定义的枚举,那可以直接把构建Property的逻辑封装到枚举自身里,代码会更简洁:
public enum FieldType { Keyword { @Override public Property toProperty() { return Property.of(p -> p.keyword(k -> k)); } }, Boolean { @Override public Property toProperty() { return Property.of(p -> p.boolean_(b -> b)); } }, Integer { @Override public Property toProperty() { return Property.of(p -> p.integer(i -> i)); } }; // 定义抽象方法,每个枚举值实现自己的构建逻辑 public abstract Property toProperty(); }
之后调用的时候就超级简单了,直接:
FieldType type = ...; Property prop = type.toProperty();
这种方式把类型和它的构建逻辑紧耦合在一起,逻辑更内聚,新增类型时只需要加一个枚举值并实现toProperty方法就行。
内容的提问来源于stack exchange,提问作者Alain Désilets
相关产品推荐
相关产品推荐

