Java枚舉類在生產環境中的使用方式

前言

  Java枚舉在項目中使用非常普遍,許多人在做項目時,一定會遇到要維護某些業務場景狀態的時候,往往會定義一個常量類,然後添加業務場景相關的狀態常量。但實際上,生產環境的項目中業務狀態的定義大部分是由枚舉類來完成的,因為更加清晰明確,還能自定義不同的方法來獲取對應的業務狀態值,十分方便。

  以下代碼均為生產環境已上線項目的代碼片段,僅供參考。

使用

  大體分為確定業務場景狀態、定義枚舉類、自定義查詢方法、測試效果等幾個部分。

1、確定業務場景狀態

  以我工作中實際的項目為例,智慧醫院在挂號、門診繳費時需要使用支付功能,我們目前實現了以下幾種支付形式:微信小程序支付、微信H5支付、支付寶小程序支付、支付寶生活號支付、微信醫保支付。
  那麼,我們就可以針對這幾種支付形式定義一個枚舉類專門維護,今後需要新增、修改以及刪除時,只需要修改這個枚舉類即可。

2、定義枚舉類
public enum PayTypeEnum {

    WEI_XIN_MINI_APP("1", "wxma", "微信小程序支付"),

    WEI_XIN_H5("2", "wxh5", "微信H5支付"),

    ZFB_MINI_APP("3", "zfbma", "支付寶小程序支付"),

    ZFB_H5("4", "zfbh5", "支付寶生活號支付"),

    WEI_XIN_MEDICAL("5", "wxmedical", "微信醫保支付");

    private final String id;
    private final String code;
    private final String label;

    PayTypeEnum(final String id, final String code, final String label) {
        this.id = id;
        this.code = code;
        this.label = label;
    }

    public String getId() {
        return id;
    }

    public String getCode() {
        return code;
    }

    public String getLabel() {
        return label;
    }

}

3、自定義查詢方法

  枚舉類我們定義了id、code、label,那麼我們使用過程中可能需要根據id獲取枚舉值、根據code獲取枚舉值(本人大部分時候都定義的這兩個),甚至根據label獲取枚舉值,因此可以根據需要自定義自己的查詢方法。

/**
 * 根據id獲取枚舉對象
 * @param id 
 */
public static PayTypeEnum findById(String id) {
    for (PayTypeEnum type : PayTypeEnum.values()) {
        if (type.getId().equals(id))
            return type;
    }
    return null;
}

/**
 * 根據code獲取枚舉對象
 * @param code 
 */
public static PayTypeEnum findByCode(String code) {
    for (PayTypeEnum type : PayTypeEnum.values()) {
        if (type.getCode().equals(code))
            return type;
    }
    return null;
}

  為了更完善,我們還可以再定義一個檢查枚舉類型的方法。

/**
 * 檢查支付類型是否有效
 * @param id 
 */
public static void check(String id) {
    if (StringUtils.isEmpty(id)) {
        throw new BadRequestAlertException("無效的支付類型", "PayTypeEnum", "無效的支付類型");
    }
    for (PayTypeEnum type : PayTypeEnum.values()) {
        if (type.getId().equals(id)) {
            return;
        }
    }
    throw new BadRequestAlertException("無效的支付類型", "PayTypeEnum", "無效的支付類型");
}

  最終代碼如下:

import com.web.rest.errors.BadRequestAlertException;
import org.springframework.util.StringUtils;

public enum PayTypeEnum {

    WEI_XIN_MINI_APP("1", "wxma", "微信小程序支付"),

    WEI_XIN_H5("2", "wxh5", "微信H5支付"),

    ZFB_MINI_APP("3", "zfbma", "支付寶小程序支付"),

    ZFB_H5("4", "zfbh5", "支付寶生活號支付"),

    WEI_XIN_MEDICAL("5", "wxmedical", "微信醫保支付");

    private final String id;
    private final String code;
    private final String label;

    PayTypeEnum(final String id, final String code, final String label) {
        this.id = id;
        this.code = code;
        this.label = label;
    }

    public String getId() {
        return id;
    }

    public String getCode() {
        return code;
    }

    public String getLabel() {
        return label;
    }

    /**
     * 根據id獲取枚舉對象
     * @param id 
     */
    public static PayTypeEnum findById(String id) {
        for (PayTypeEnum type : PayTypeEnum.values()) {
            if (type.getId().equals(id))
                return type;
        }
        return null;
    }

    /**
     * 根據code獲取枚舉對象
     * @param code
     */
    public static PayTypeEnum findByCode(String code) {
        for (PayTypeEnum type : PayTypeEnum.values()) {
            if (type.getCode().equals(code))
                return type;
        }
        return null;
    }

    /**
     * 檢查支付類型是否有效
     * @param id 
     */
    public static void check(String id) {
        if (StringUtils.isEmpty(id)) {
            throw new BadRequestAlertException("無效的支付類型", "PayTypeEnum", "無效的支付類型");
        }
        for (PayTypeEnum type : PayTypeEnum.values()) {
            if (type.getId().equals(id)) {
                return;
            }
        }
        throw new BadRequestAlertException("無效的支付類型", "PayTypeEnum", "無效的支付類型");
    }

}

4、測試效果
public static void main(String[] args) {

   System.out.println("============= 獲取枚舉類的值 =============");
   System.out.println("獲取id:" + PayTypeEnum.WEI_XIN_MINI_APP.getId());
   System.out.println("獲取code:" + PayTypeEnum.WEI_XIN_MINI_APP.getCode());
   System.out.println("獲取label:" + PayTypeEnum.WEI_XIN_MINI_APP.getLabel());


   System.out.println("============= 根據自定義的查詢方法獲取值 =============");
   System.out.println("根據id獲取枚舉對象:" + PayTypeEnum.findById("3"));
   System.out.println("根據code獲取枚舉對象:" + PayTypeEnum.findByCode("zfbma"));


   System.out.println("============= 類型有效性檢查 =============");
   System.out.print("檢查1:");
   PayTypeEnum.check("1");
   System.out.println();
   System.out.print("檢查2:");
   PayTypeEnum.check("999");
}

  打印如下:

============= 獲取枚舉類的值 =============
獲取id:1
獲取code:wxma
獲取label:微信小程序支付
============= 根據自定義的查詢方法獲取值 =============
根據id獲取枚舉對象:ZFB_MINI_APP
根據code獲取枚舉對象:ZFB_MINI_APP
============= 類型有效性檢查 =============
檢查1:
檢查2:無效的支付類型

Process finished with exit code 0

總結

  Java枚舉類的定義,大部分都和業務場景有關,但凡是類似於業務狀態值的定義,最好都使用枚舉類,這樣便於維護和閱讀,但每個工程師和研發團隊的風格都是不同的,僅以個人這些年的工作經歷而言,往往參與一個項目,到後期會形成大量的枚舉類,而不是大量的常量類,常量類頂多只有一個,太多的話根本無法維護,尤其是人員變更之後,新來的同事對於大量的常量類感到頭疼,但枚舉類卻能清晰的表達該業務的場景及用法。

  如果喜歡的話,麻煩一鍵……啊不,點個贊 ,覺得有用也可以點個推薦咯~(o..o)

Tags: