It is comparatively easy to make much of the work around enums generic.
Here's a severely cut-down example. It defines a generic database Table
class that takes an enum Column
as its defining type. The enum
defines what columns are in the table. The defining type is an enum
that also implements an interface which is a really useful trick.
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;
}
}
You can now create your real table with something like:
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));
}
}
Note that this is a truly trivial example but with a little work it is easy to move a lot of your enum
work into the parent class.
This technique does retain the type-safety checks you get when using generics.