在上一篇博客里,我編寫(xiě)了一個(gè)UserType,實(shí)現(xiàn)了持久化自定義的enum類,其實(shí)那個(gè)例子中存在兩個(gè)缺點(diǎn)。這兩個(gè)缺點(diǎn)是關(guān)于如何正確使用enum以及generic的,她們已經(jīng)和hibernate userType無(wú)關(guān)了,因此另起一個(gè)主題討論。
在上一篇博客中,我的enum是這么寫(xiě)的:
其中兩個(gè)static方法是為了方便使用。
缺點(diǎn)一:
所有的enum實(shí)例必須手動(dòng)納入list集合中。
解決方法:
解決方法非常簡(jiǎn)單,是用Class類提供的方法getEnumConstants(), 代碼如下:
我個(gè)人比較討厭數(shù)組,因此這里特意將數(shù)組轉(zhuǎn)換成List。如果你們不介意使用數(shù)組的話,getAll()方法完全可以省略。
缺點(diǎn)二:
findById(Integer id) 方法名并不貼切,叫g(shù)etEnumById(Integer id)會(huì)更好些。另外一模一樣的方法必須在每一個(gè)enum類中重復(fù)編寫(xiě),如果某個(gè)地方需要改動(dòng),那就需要改動(dòng)所有相關(guān)的enum類,這是一個(gè)很明顯的bad smell。
解決方法:
編寫(xiě)一個(gè)util類,將邏輯轉(zhuǎn)移到util類中,getEnumById(Integer id)方法調(diào)用util類中的相關(guān)方法,代碼如下:
這里getEnum(Class<I> type, int id)方法利用Java 5的新特性generic,利用給定的Class和enum id,返回對(duì)應(yīng)的enum實(shí)例。這樣處理好處很明顯,獲取enum實(shí)例的邏輯代碼只存在與util類中,日后修改十分方便。
相關(guān)內(nèi)容請(qǐng)參閱我寫(xiě)的《Hibernate 3和Java Persistence API 程序開(kāi)發(fā)從入門(mén)到精通》一書(shū)。
聲明:本文版權(quán)歸作者所有,如需轉(zhuǎn)載請(qǐng)注明出處。
在上一篇博客中,我的enum是這么寫(xiě)的:
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;
}
}
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;
}
}
其中兩個(gè)static方法是為了方便使用。
缺點(diǎn)一:
所有的enum實(shí)例必須手動(dòng)納入list集合中。
解決方法:
解決方法非常簡(jiǎn)單,是用Class類提供的方法getEnumConstants(), 代碼如下:
public static List<Status> getAll() {
return Arrays.asList(Status.class.getEnumConstants());
}
return Arrays.asList(Status.class.getEnumConstants());
}
我個(gè)人比較討厭數(shù)組,因此這里特意將數(shù)組轉(zhuǎn)換成List。如果你們不介意使用數(shù)組的話,getAll()方法完全可以省略。
缺點(diǎn)二:
findById(Integer id) 方法名并不貼切,叫g(shù)etEnumById(Integer id)會(huì)更好些。另外一模一樣的方法必須在每一個(gè)enum類中重復(fù)編寫(xiě),如果某個(gè)地方需要改動(dòng),那就需要改動(dòng)所有相關(guān)的enum類,這是一個(gè)很明顯的bad smell。
解決方法:
編寫(xiě)一個(gè)util類,將邏輯轉(zhuǎn)移到util類中,getEnumById(Integer id)方法調(diào)用util類中的相關(guān)方法,代碼如下:
public static Status getEnumById(Integer id) {
return EnumUtils.getEnum(Status.class, 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;
}
}
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,返回對(duì)應(yīng)的enum實(shí)例。這樣處理好處很明顯,獲取enum實(shí)例的邏輯代碼只存在與util類中,日后修改十分方便。
相關(guān)內(nèi)容請(qǐng)參閱我寫(xiě)的《Hibernate 3和Java Persistence API 程序開(kāi)發(fā)從入門(mén)到精通》一書(shū)。
聲明:本文版權(quán)歸作者所有,如需轉(zhuǎn)載請(qǐng)注明出處。