最近發現蠻多人會在業務邏輯程式中直接使用Enum.valueOf(String arg0)
將傳入的字串轉為對應的Enum型別,而這樣是好的寫法嗎?
先說結論,不應該在業務邏輯中(例如Service層)使用Enum.valueOf(String arg0)
,此方法應該只在Enum內部使用,原因如下。
例如現在有個簡單的Enum型別CardType
,有兩個列舉CREDIT
與DEBIT
分別表示信用卡與簽帳卡。
public enum CardType {
CREDIT, DEBIT;
}
由於傳來的字串參數會是各種樣式,若在業務邏輯中直接用valueOf()
,若傳入的參數不同於列舉本身的文字,就會造成java.lang.IllegalArgumentException
錯誤。
例如下面的方法會根據傳入的cardType
判斷為信用卡還是簽帳卡去不同的資料表撈取客戶資料。
public Customer getCustomer(String cardNumber, String cardType) {
CardType type = CardType.valueOf(cardType); // IllegalArgumentException if cardType is not "CREDIT" or "DEBIT"
switch(type) {
case CREDIT:
// query Credit Card Table
break;
case DEBIT:
// query Debit Card Table
break;
}
//...
}
在上面的方法中,如果cardType
字串不是"CREDIT"
或"DEBIT"
就會丟出IllegalArgumentException
導致程式停止。
傳入的字串不但文字要相同,大小寫也要相同。
CardType.valueOf("CREDIT");
CardType.valueOf("credit"); // 發生IllegalArgumentException錯誤
也就是說使用Enum.valueOf(String arg0)
前都必須檢查傳入的字串是否符合列舉的名稱,以文字大小寫不同為例,有的人可能會這樣寫。
public Customer getCustomer(String cardNumber, String cardType) {
CardType type = CardType.valueOf(cardType.toUpperCase()); // 轉成大寫
switch(type) {
case CREDIT:
// query Credit Card Table
break;
case DEBIT:
// query Debit Card Table
break;
}
//...
}
但這樣的問題是所有業務邏輯中有用到valueOf()
的地方都要用toUpperCase()
轉成大寫。此外如果傳入的字串是null
每個地方還要加上null
的檢查。當用到的地方一多很容易疏漏要做的檢查,而且若有改動全部的地方都要修改非常麻煩。
所以在業務邏輯中要轉字串為對應的Enum,應該集中在Enum中寫一個統一的轉換方法如下。當業務邏輯中要轉字串為Enum時就呼叫此方法。
public enum CardType {
CREDIT, DEBIT;
public static CardType getEnum(String value) {
if (value == null || value.length() < 1) {
return null;
}
for (CardType t : values()) {
if (t.name().equalsIgnoreCase(value)) {
return t;
}
}
return null;
}
}
業務邏輯中改為如下。
public Customer getCustomer(String cardNumber, String cardType) {
CardType type = CardType.getEnum(cardType); // <--
switch(type) {
case CREDIT:
// query Credit Card Table
break;
case DEBIT:
// query Debit Card Table
break;
}
//...
}
參考:
沒有留言:
張貼留言