我有一个代码,最初是为一个团队设计的,他们将枚举 [存储任务列表] 传递给 api。然后,此 api 将此枚举的使用传播到许多其他类。
现在我有一个任务需要多个团队使用此代码,他们可以以枚举的形式传递自己的一组任务。
鉴于当前的实现,我认为支持多个团队彻底检查代码是不可行的,因为枚举不能扩展其他枚举。
有没有什么方法可以在不进行大量更改的情况下实现这一点?
但是...枚举可以实现接口,例如:
public interface Task {
int getPriority(); // just for example
// plus whatever methods define a task
}
public enum Team1Task implements Task {
Task1(1),
Task2(3);
private final int priority;
private Team1Task(int priority) {
this.priority = priority;
}
public int getPriority() {
return priority;
}
}
现在我们可以使用 java generic kung fu 来指定一个绑定到合适枚举的泛型参数:
public class TaskProcessor<T extends Enum<T> & Task> {
public void process(T task) {
// do something with task
}
}
要使用它:
TaskProcessor<Team1Task> p = new TaskProcessor<Team1Task>();
p.process(Team1Task.Open); // will only accept a Team1Task instance
仅供参考,出于对泛型的好奇,您也可以使用此绑定来实现相同的目的:
public class TaskProcessor<T extends Enum<? extends Task>> {
虽然我在效果上没有发现实际差异,但我发现它缺乏上面交叉绑定的清晰和熟悉的模式。有关这方面的更多信息,请参阅此问题。
围绕枚举进行大部分工作相对容易。
这是一个严重削减的例子。它定义了一个通用数据库Table
类,该类将 aenum Column
作为其定义类型。定义表中的enum
列。定义类型是一个enum
也实现了一个非常有用的技巧的接口。
public class Table<Column extends Enum<Column> & Table.Columns> {
// Name of the table.
protected final String tableName;
// All of the columns in the table. This is actually an EnumSet so very efficient.
protected final Set<Column> columns;
/**
* The base interface for all Column enums.
*/
public interface Columns {
// What type does it have in the database?
public Type getType();
}
// Small list of database types.
public enum Type {
String, Number, Date;
}
public Table(String tableName,
Set<Column> columns) {
this.tableName = tableName;
this.columns = columns;
}
}
您现在可以使用以下内容创建您的真实表格:
public class VersionTable extends Table<VersionTable.Column> {
public enum Column implements Table.Columns {
Version(Table.Type.String),
ReleaseDate(Table.Type.Date);
final Table.Type type;
Column(Table.Type type) {
this.type = type;
}
@Override
public Type getType() {
return type;
}
}
public VersionTable() {
super("Versions", EnumSet.allOf(Column.class));
}
}
请注意,这是一个真正微不足道的示例,但只需进行少量工作,就可以轻松地将大量enum
工作移至父类中。
这种技术确实保留了您在使用泛型时获得的类型安全检查。
枚举可以实现接口。我建议为该任务提供一个合理的界面。让您的枚举实现接口,您的代码将继续正常工作。其他团队可以使用他们想要的任何接口实现(他们自己的枚举或其他东西)。(注意,没有代码很难做出非常明确的建议)。
您可能不应该为此使用枚举,但如果您愿意,您可以在帮助类或相互扩展的一组类中实现逻辑,并使枚举成为围绕它的薄包装器:
public enum MyTaskEnum {
A, B, C;
private final TaskEnumHelper helper = new TaskEnumHelper();
public void foo (int x, int y)
{
helper.foo (x, y);
}
}