繁体   English   中英

模仿可扩展枚举行为的综合正确方法是什么?

[英]What'd be the synthetically correct way of imitating extendable enum behavior?

传统上,当我有一个枚举时:

public enum SomeEnum implements Serializable {
    TYPE_1,
    TYPE_2;
}

或 class:

public class Country {

    public static final Country SOME_COUNTRY = new Country("someCode");

    private final String code;

    ...
}

在 controller 中,我返回这些值以填充一些选择:

@RestController(...)
public List<Field> getFields() {

    return Arrays.asList(SomeEnum.class.getEnumConstants());

    // or

    return Arrays.asList(Country.class.getDeclaredFields());
}

目前,我正在开发一个可以由某些最终产品导入的 webhook 库。 一些事件名称来自库本身,但其中一些不存在于库中(但在最终产品代码中):

Webhook class 看起来像这样:

public class Webhook {

    private String url;

    private List<WebhookEvent> events;

    ...
}

WebhookEvent如下:

public class WebhookEvent Serializable {

    private long id;

    private String name;

    ...
}

并且WebhookEvent是从数据库中填充的。 不想在最终产品中创建控股 class,例如:

public class EnabledEvent {

    public static final WebhookEvent SOME_EVENT = new WebhookEvent("event.name");

    ...
}

因为那会从两个不同的点控制应用程序的行为。 但是相反,我希望能够在数据库中有新条目时立即返回这些常量/字段。 基本上我希望能够模仿基于数据库中的条目扩展常量/枚举的行为。 是否有以编程方式实现此目的的正确方法?

在我们的例子中,我们必须验证许多常量。 这个常量文件开始堆积。 因此,我们不得不以不同的方式 devise 并最终仅为常量创建一个单独的表,因此您可以添加或删除/禁用不需要的一次,而无需重新编译您的代码(尽管您必须这样做,如果有依赖项案件)。

例如,假设您具有以下患者状态 (STATUS):

稳定、危急、死亡、恢复和 NA

以及 TEST_RESULT 的以下状态:

TEST_PENDING、TEST_NEGATIVE 和 TEST_POSITIVE

该表看起来像:

------------------------------------------------------------------------
enum_code       enum_type       enum_name       enum_desc       disabled
------------------------------------------------------------------------
001             STATUS          STABLE                          false
002             STATUS          CRITICAL                        false
003             STATUS          DECEASED                        false
004             STATUS          RECOVERED                       false
005             STATUS          NA                              false
100             TEST_RESULT     TEST_PENDING                    false
101             TEST_RESULT     TEST_NEGATIVE                   false
102             TEST_RESULT     TEST_POSITIVE                   false
------------------------------------------------------------------------
@Entity
@Table(name="constant_enum")
public class ConstantEnum implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name="enum_code")
    private Integer enumCode;
    
    private boolean disabled;
    
    @Column(name="enum_desc")
    private String enumDesc;
    
    
    @Column(name="enum_name")
    private String enumName;

    @Column(name="enum_type") // this is the discriminator
    private String enumType;
    
    //getters and setters

}

我最终删除了与数据库的连接,并在 class 本身中定义了 static 个变量,使用 static ofValue方法来创建对象:

public class SomeClass implements Serializable {

    public static final SomeClass MY_CONSTANT_1 = new SomeClass("static.value");

    public static SomeClass [] values = new SomeClass []{
            SomeClass .MY_CONSTANT_1,
            ...
    };

    private String name;

    public SomeClass (String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public static SomeClass ofValue(String name){
        if(StringUtils.isEmpty(name)) return null;
        for(SomeClass value : values) if(value .getName().equalsIgnoreCase(name)) return event;
        throw new IllegalArgumentException(String.format("Couldn't convert value : %s into a valid %s object", name, SomeClass.class.getName()));
    }
}

这样,它可以扩展如下:

public class ExtendedSomeClass extends SomeClass implements Serializable {

    public static final SomeClass MY_CONSTANT_2 = new SomeClass ("static.value.2");

    public static SomeClass[] values = new SomeClass[]{
            SomeClass.MY_CONSTANT_2,
    };

    public static SomeClass ofValue(String name){
        if(StringUtils.isEmpty(name)) return null;
        for(SomeClass event : values) if(event.getName().equalsIgnoreCase(name)) return event;
        return SomeClass.ofEvent(name);
    }
}

我总是可以连接values arrays 并从@RestController端点返回它以填充 forms。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM