在上一篇博客里,我編寫了一個UserType,實現了持久化自定義的enum類,其實那個例子中存在兩個缺點。這兩個缺點是關于如何正確使用enum以及generic的,她們已經和hibernate userType無關了,因此另起一個主題討論。
在上一篇博客中,我的enum是這么寫的:
public enum Status implements DescriptionID {
ACTIVATED(5, "This object is activated"),
DEACTIVATED(9, "This object is deactivated");
private Integer id;
private String description;
private static List<Status> list;
static {
list = new ArrayList<Status>(2);
list.add(ACTIVATED);
list.add(DEACTIVATED);
}
private Status(int statusNr, String description) {
this.id = statusNr;
this.description = description;
}
public String getDescription() {
return this.description;
}
public Integer getId() {
return id;
}
public static List<Status> getAll() {
return list;
}
public static Status findById(Integer id) {
for (Status status : getAll()) {
if (id == status.getId()) {
return status;
}
}
return null;
}
}
其中兩個static方法是為了方便使用。
缺點一:
所有的enum實例必須手動納入list集合中。
解決方法:
解決方法非常簡單,是用Class類提供的方法getEnumConstants(), 代碼如下:
public static List<Status> getAll() {
return Arrays.asList(Status.class.getEnumConstants());
}
我個人比較討厭數組,因此這里特意將數組轉換成List。如果你們不介意使用數組的話,getAll()方法完全可以省略。
缺點二:
findById(Integer id) 方法名并不貼切,叫getEnumById(Integer id)會更好些。另外一模一樣的方法必須在每一個enum類中重復編寫,如果某個地方需要改動,那就需要改動所有相關的enum類,這是一個很明顯的bad smell。
解決方法:
編寫一個util類,將邏輯轉移到util類中,getEnumById(Integer id)方法調用util類中的相關方法,代碼如下:
public static Status getEnumById(Integer id) {
return EnumUtils.getEnum(Status.class, id);
}
public class EnumUtils {
public static <I extends DescriptionID> I getEnum(Class<I> type, int id) {
I[] types = type.getEnumConstants();
for (I t : types) {
if (t.getId() == id)
return t;
}
return null;
}
}
這里getEnum(Class<I> type, int id)方法利用Java 5的新特性generic,利用給定的Class和enum id,返回對應的enum實例。這樣處理好處很明顯,獲取enum實例的邏輯代碼只存在與util類中,日后修改十分方便。
相關內容請參閱
我寫的《Hibernate 3和Java Persistence API 程序開發從入門到精通》一書。
聲明:本文版權歸作者所有,如需轉載請注明出處。