在处理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如何处理这种“语言功能”?
答案 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;
}
}