扩展Java枚举

时间:2012-01-10 16:05:36

标签: java enums

在处理Java枚举时,我对代码重用的最佳设计模式有疑问。基本上,我想要实现的是能够定义几个模拟静态业务集合(常量集)的枚举,但我也想用最少的编码来共享它们之间的行为。

通过抽象类的类继承实现这是微不足道的,但是,由于Java枚举无法扩展(它们只能实现接口),这种类型的工作很繁琐,并且涉及很多容易出错的复制/粘贴工作(复制代码从枚举到枚举)。应在所有枚举之间共享的“业务逻辑”示例包括从/转换为字符串,实例和逻辑比较等。

我现在最好的方法是将helper类与业务接口结合使用,但这只会降低代码复杂性(因为所有枚举仍然必须声明并调用辅助类)。参见示例(只是为了澄清):

public enum MyEnum {
    A, B, C;

    // Just about any method fits the description - equals() is a mere example
    public boolean equals(MyEnum that) {
        ObjectUtils.equals(this, that);
    }
} 

StackOverflowers如何处理这种“语言功能”?

4 个答案:

答案 0 :(得分:3)

您可以将可重用逻辑移动到专用(非枚举)类,然后让枚举委托给这些类。这是一个例子:

[附注:不推荐PlusTwo extends PlusOne的继承(b / c PlusTwo不是PlusOne)。这只是为了说明能够扩展现有逻辑的观点。]

public interface Logic {
  public int calc(int n);
}

public static class PlusOne implements Logic {
  public int calc(int n) { return n + 1; }
}

public static class PlusTwo extends PlusOne {
  @Override
  public int calc(int n) { return super.calc(n) + 1; }
}

public static enum X {
  X1, X2;   
  public Logic logic;

  public int doSomething() { 
    return logic.calc(10);
  }
}

public static enum Y {
  Y1, Y2;
  public Logic logic;

  public String doSomethingElse() { 
    return "Your result is '" + logic.calc(10) + "'";
  }
}

public static void main(String[] args) {
  // One time setup of your logic:
  X.X1.logic = new PlusOne();
  X.X2.logic = new PlusTwo();  
  Y.Y1.logic = new PlusOne();
  Y.Y2.logic = new PlusTwo();

  System.out.println(X.X1.doSomething());
  System.out.println(X.X2.doSomething());
  System.out.println(Y.Y1.doSomethingElse());
  System.out.println(Y.Y2.doSomethingElse());
}

答案 1 :(得分:2)

我也会这样做,或者将Enums组合成一个超级枚举。

使用Java 8,这将更容易。您将能够为接口方法定义default实现,并使enum扩展接口。

答案 2 :(得分:2)

我很少发现enums有用,除了代表有限状态,在这种情况下他们不需要行为。

我建议使用enums将需要行为的classes重构为Factory

答案 3 :(得分:0)

这可能看起来有点难看,但通常可以为您提供所需的功能。

您可以拥有界面

public interface MyEnumInterface<T extends Enum<T>> {

    String getBusinessName();

    T getEnum();

}

实施

public enum OneOfMyEnums implements MyEnumInterface<OneOfMyEnums>{

    X, Y, Z;

    @Override
    public String getBusinessName() {
        return "[OneOfMyEnums]" + name();
    }

    @Override
    public OneOfMyEnums getEnum() {
        return this;
    }

}

实用程序类而不是父类

public class MyEnumUtils {

    public static <T extends Enum<T>> String doSomething(MyEnumInterface<T> e){
        e.getBusinessName(); // can use MyEnumInterface methods
        e.getEnum().name(); // can use Enum methods as well
        return null;
    }

}