Java中的枚舉的治理


版權聲明:本文為博主原創文章,轉載請注明出處,歡迎使勁噴

一、為啥用枚舉&為啥要對枚舉進行治理

  1.先來說說為啥用枚舉

    表中某個字段標識了這條記錄的狀態,我們往往使用一些code值來標識,例如01成功,00失敗。

    多狀態共性的東西可以常量保存,例如

      class Constants{
        public static final String success = "01";         public static final String failure= "00";       }

    然而,在一些大型項目中,表的數量極多,一些表中需要維護的狀態也極多,如果都在如上的Constants中維護,試想如果添加一個狀態值,那么需要在整個篇幅中找到對應的塊,然后去新增值;修改呢?同樣麻煩!!!

    所以我們使用枚舉,每個枚舉類就只負責對一個狀態做維護,這樣我們方便增刪改。例如:

/**
 * Created by Bright on 2017/3/13.
 *
 * @author :
 */
public enum Payment {
    Payment_WX("010000","微信支付"), Payment_ZFB("010001","支付寶支付"), Payment_YL("010002","銀聯支付"); public static Map<String,String> map = new HashMap<String, String>(); static{ Payment[] values = Payment.values(); if(values.length > 0){ for(Payment product : values){ map.put(product.getCode(),product.getName()); } } } Payment(String code, String name){ this.code = code; this.name = name; } private String code; private String name; public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getName() { return name; } public void setName(String name) { this.name = name; } }

  2.為啥要用java反射處理枚舉呢?

    我們之前看到了,使用Constants很方便,可以直接通過這個類的靜態字段拿到值。當我們使用枚舉時,當枚舉類逐漸增多時,我們會發現,不同的地方我們需要獲取不同的類,然后再通過不同的枚舉獲取到不同的值。這又勢必是個頭痛的事情。

    那么我們想到了改進的方法:

      改進一:把每個枚舉類中放個map,把其code和name值映射進去,然后調用時通過靜態map對象,把code值作為key傳入,勢必能獲取到對應的描述。(如上段代碼的map值) 

    然而,這個改進后,我們依舊需要找到這個類,然后去使用它的靜態map,能不能只通過一個類進行統一治理呢?

      改進二:通過一個類,把所有枚舉在該類中注冊,然后通過該類直接獲取到相應的枚舉值及name描述。 

二、枚舉治理的實現

  1.先弄清我們使用枚舉的場景

    1.1通過枚舉類中枚舉名獲取到枚舉的code值(使用上面的枚舉值定義)

      例如:{"Payment_WX":"010000","Payment_YL":"010002","Payment_ZFB":"010001"}

if(param.equals(Payment.Payment_WX.getCode()){}

    1.2通過枚舉類中枚舉的code值獲取到對應的name描述(使用上面的枚舉值定義)

      例如:{"010002":"銀聯支付","010001":"支付寶支付","010000":"微信支付"}

Payment.map.get(Payment.Payment_WX.getCode());

  2.枚舉治理工具類的實現

/**
 * Created by Bright on 2017/3/13.
 *
 * @author :
 */
public class VelocityEnumTools {

    public static final Logger logger = LoggerFactory.getLogger(VelocityEnumTools.class); //通過枚舉獲取枚舉code值,例如:{"Payment_WX":"010000","Payment_YL":"010002","Payment_ZFB":"010001"} public static Map<String,Map<String,String>> mapKeyCode = new HashMap<String, Map<String, String>>(); //通過code值獲取枚舉name,例如:{"010002":"銀聯支付","010001":"支付寶支付","010000":"微信支付"} public static Map<String, Map<String, String>> mapCodeName = new HashMap<String, Map<String, String>>(); /** * 需要在頁面控制的enum,如Payment類似添加即可 */ static { //通過枚舉獲取code值 mapKeyCode.put(Payment.class.getSimpleName(), getEnumMap(Payment.class)); //通過code值獲取枚舉name mapCodeName.put(Payment.class.getSimpleName(),getEnumCodeMap(Payment.class)); } /** * 通過枚舉獲取code值 * @param enumKey * @return */ public static Map<String, String> getKeyCodeMapperInstance(String enumKey) { return mapKeyCode.get(enumKey); } /** * 通過code值獲取枚舉name * @param enumKey * @return */ public static Map<String, String> getCodeNameMapperInstance(String enumKey) { return mapCodeName.get(enumKey); } public static <T> Map<String, String> getEnumMap(Class<T> clazz) { Map<String, String> map = new HashMap<String, String>(); try { if (clazz.isEnum()) { Object[] enumConstants = clazz.getEnumConstants(); for (int i = 0; i < enumConstants.length; i++) { T t = (T) enumConstants[i]; Field code = t.getClass().getDeclaredField("code"); code.setAccessible(true); map.put(t.getClass().getDeclaredFields()[i].getName(), (String) code.get(t)); } } } catch (NoSuchFieldException e) { logger.error("枚舉工具啟動報錯:{}", e); } catch (IllegalAccessException e) { logger.error("枚舉工具啟動報錯:{}", e); } return map; } private static <T> Map<String,String> getEnumCodeMap(Class<T> clazz) { Map<String, String> map = new HashMap<String, String>(); try { if (clazz.isEnum()) { Object[] enumConstants = clazz.getEnumConstants(); for (int i = 0; i < enumConstants.length; i++) { T t = (T) enumConstants[i]; Field code = t.getClass().getDeclaredField("code"); Field name = t.getClass().getDeclaredField("name"); code.setAccessible(true); name.setAccessible(true); map.put((String) code.get(t),(String) name.get(t)); } } } catch (NoSuchFieldException e) { logger.error("枚舉工具啟動報錯:{}", e); } catch (IllegalAccessException e) { logger.error("枚舉工具啟動報錯:{}", e); } return map; } public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException { Map<String, String> enumMap = getEnumMap(Payment.class); System.out.println(JSON.toJSONString(enumMap));//{"Payment_WX":"010000","Payment_YL":"010002","Payment_ZFB":"010001"} Map<String, String> enumCodeMap = getEnumCodeMap(Payment.class); System.out.println(JSON.toJSONString(enumCodeMap));//{"010002":"銀聯支付","010001":"支付寶支付","010000":"微信支付"} } }

 

三、枚舉治理的擴展-velocity中使用枚舉

  1.為什么會在velocity中使用枚舉

  當涉及與前端的交互時,我們可能需要從前端把三種支付方式對應的code值傳到后台。

  此時,如果在頁面上直接寫010000這樣的值,那么頁面的邏輯就很不直觀了,今天寫的時候你還能認知,為了防止自己忘了,除了加注釋別無辦法。

故,為了解決后台可用,且前端頁面直觀,所以我們希望嘗試在頁面上直接用枚舉來解決問題。

2.看看頁面如何處理(velocity頁面中)

#set($payment=$enumTool.getCodeNameMapperInstance("Payment"))//直接寫明要獲取的枚舉類型名稱

#if($payment.get("Payment_WX") == $param.code)//通過枚舉值獲取其code值
    //做微信支付頁面邏輯
#end

2.velocity中配置velocity-tools

<?xml version="1.0" encoding="UTF-8"?>
<toolbox>
    <tool>
        <key>enumTool</key>
        <class>com.bright.core.enumconstant.VelocityEnumTools</class>
    </tool>
    <tool>
        <key>stringTool</key>
        <class>org.apache.commons.lang.StringUtils</class>
    </tool>
    <tool>
        <key>dateTool</key>
        <class>org.apache.velocity.tools.generic.DateTool</class>
    </tool>
</toolbox>

   這樣就可以簡單的在頁面中應用我們枚舉治理工具了。

  例如:通過code值獲取到相應描述

$enumTool.getCodeNameMapperInstance("Payment").get($item.orderLoanStatus)//顯示“微信支付”

     通過枚舉獲取到對應的code值

#set($payment=$enumTool.getCodeNameMapperInstance("Payment"))//拿到了Payment的map
$payment.get("Payment_WX")

  就此,我們可以實現系統的中的枚舉治理,並且可在前端頁面靈活應用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM