我试图找出是否有一种干净的方法来做到这一点.我想设计一个ENUM来维护我的应用程序中不同组件的常量值列表.每个枚举将具有相同的配置和相同的参数,但至少会因组件名称而不同.
在普通的Java类中,我可以在基本抽象类中构建所有基本逻辑/代码,并使每个组件常量扩展抽象类并仅填充其自己的相关信息.但是,Java枚举不允许扩展现有类.
有什么我可以做的,以避免必须将所有常量推入单个枚举(ugggg!)或每次为每个不同的组件重新创建相同的枚举类?在这种情况下绝对不是DRY,但我不知道如何避免这个问题.
一个快速的用例示例.假设我想在Enum中保留所有请求映射的列表,以便在我的应用程序的其他地方使用.相当容易设计枚举说:
public enum RequestMapping {
INDEX("index"),
GET_ALL_USERS( "getAllUsers");
private String requestMapping = "/users";
private String path;
RatesURI( String path ){
this.path = path;
}
public String getRequestMapping(){
return requestMapping;
}
public String getPath(){
return path;
}
public String getFullRequestPath(){
return requestMapping + "/" + path;
}
}
Run Code Online (Sandbox Code Playgroud)
使用RequestMapping.GET_ALL_USERS.getFullRequestPath()变得很容易.
现在,如果我想在每个控制器的基础上创建这个枚举,我将不得不重新创建整个Enum类并更改每个枚举的"requestMapping"值.当然,这个枚举几乎没有代码,所以重复它并不困难,但这个概念仍然存在.理论上"干净"的方法是使用包含所有方法的抽象AbstractRequestMapping类型,包括抽象的getRequestMapping()方法,并且只有扩展的Enums实现特定于控制器的getReqeuestMapping().当然,由于Enums无法扩展,我无法想到这样做的非DRY方式.
您是否考虑过扩展一个作为Enum通用参数的类?这是一个非常灵活的机制。
public class Entity<E extends Enum<E> & Entity.IE> {
// Set of all possible entries.
// Backed by an EnumSet so we have all the efficiency implied along with a defined order.
private final Set<E> all;
public Entity(Class<E> e) {
// Make a set of them.
this.all = Collections.unmodifiableSet(EnumSet.<E>allOf(e));
}
// Demonstration.
public E[] values() {
// Make a new one every time - like Enum.values.
E[] values = makeTArray(all.size());
int i = 0;
for (E it : all) {
values[i++] = it;
}
return values;
}
// Trick to make a T[] of any length.
// Do not pass any parameter for `dummy`.
// public because this is potentially re-useable.
public static <T> T[] makeTArray(int length, T... dummy) {
return Arrays.copyOf(dummy, length);
}
// Example interface to implement.
public interface IE {
@Override
public String toString();
}
}
class Thing extends Entity<Thing.Stuff> {
public Thing() {
super(Stuff.class);
}
enum Stuff implements Entity.IE {
One,
Two;
}
}
Run Code Online (Sandbox Code Playgroud)
您可以通过多种不同的方式将实现的性质传递给父类 -enum.class为了简单起见,我使用了这种方式。
您甚至可以使该enum实现成为您所看到的接口。
该values方法仅用于演示。一旦您可以访问Set<E>父类中的 ,您只需通过扩展 即可提供各种功能Entity。