如何使用只有一个参数在实例化之间不同的Java Enum DRY?

Eri*_* B. 6 java enums

我试图找出是否有一种干净的方法来做到这一点.我想设计一个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方式.

Old*_*eon 4

您是否考虑过扩展一个作为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