Enum Tools 減少枚舉中重複的方法

背景

最近修改項目的時候發現一些好東西,對於枚舉的通用方法的處理,發現之前寫的很多重複性的勞動,總體來說對於枚舉的認識不夠,對於這些特性的使用還不是非常的屬性,編碼這個東西,總在反思、學習中成長,這種小東西也是一種成長,別看微不足道,大規模推廣使用起來,對於編碼的統一度非常的友好的。

實踐

幾乎在系統的枚舉中都是code、msg這樣的枚舉,非常的多!沒有直接的利用Enum中的name,主要是語法糖抽象的後果,看不到這個字段,很少用。一般都是通過code 獲取到枚舉,通過code 判斷是否存在個枚舉,通過code 獲取到msg … 我相信你也寫了不少的這樣的東西

反例

看起來無傷大雅,基本都能夠讀懂,但是一個系統中有很多這樣的枚舉,每個都寫一遍,你會發現非常的傷不起。但是我也寫過…

package com.wangji92.github.study.other.enums;

import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;

/**
 * 任務狀態枚舉
 *
 * @author 汪小哥
 * @date 09-03-2020
 */
@Slf4j
public enum TaskStatusEnum {
    SUCCESS("success", "成功"),
    FAIL("fail", "失敗"),
    CANCEL("cancel", "取消");

    /**
     * 編碼表示
     */
    private String code;
    /**
     * 說明
     */
    private String msg;

    public String getCode() {
        return code;
    }
    public String getMsg() {
        return msg;
    }
    TaskStatusEnum(String code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    private static Map<String, TaskStatusEnum> taskMaps = new HashMap<>();

    static {
        for (TaskStatusEnum value : TaskStatusEnum.values()) {
            taskMaps.put(value.getCode(), value);
        }
    }

    public static String getMsgByCode(String code) {
        TaskStatusEnum taskStatusEnum = getEnumByCode(code);
        String msg = taskStatusEnum != null ? taskStatusEnum.getMsg() : "";
        return msg;
    }

    public static TaskStatusEnum getEnumByCode(String code) {
        return taskMaps.get(code);
    }

    public static void main(String[] args) {
        String success = TaskStatusEnum.getMsgByCode("success");
        log.info("msg:" + success);

        boolean validEnumCode = TaskStatusEnum.getEnumByCode("success") != null;
        log.info("validEnumCode:" + validEnumCode);
    }
}

正例

繼承關係圖

TaskStatusEnumsTwo.png

實現類

enum 這個是一個語法糖,所有的都繼承了java.lang.Enum,Java不支持多繼承,只能通過接口處理咯,一個是code 一個是msg。如下所示,有區別?都是一樣的而且這裏的很多的方法都沒有啦

package com.wangji92.github.study.other.enums.enhance;

import java.io.Serializable;

/**
 * @author 汪小哥
 * @date 09-03-2020
 */
public interface EnumCode<T> extends Serializable {
    /**
     * 獲取枚舉的返回Code
     *
     * @param <T>
     * @return
     */
    T getCode();
}


/**
 * 枚舉的返回msg的信息
 *
 * @author 汪小哥
 * @date 09-03-2020
 */
public interface EnumCodeMsg<T> extends EnumCode<T> {
    /**
     * 獲取枚舉的備註信息
     * @return
     */
    String getEnumMsg();
}


/**
 * @author 汪小哥
 * @date 09-03-2020
 */
@Slf4j
public enum TaskStatusEnumsTwo implements EnumCodeMsg<String> {
    SUCCESS("success", "成功"),
    FAIL("fail", "失敗"),
    CANCEL("cancel", "取消");


    private String code;

    private String msg;

    TaskStatusEnumsTwo(String code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    @Override
    public String getEnumMsg() {
        return msg;
    }

    @Override
    public String getCode() {
        return code;
    }
}

EnumCodeMsgUtils 工具類

這裏可以添加繼承 org.apache.commons.lang3.EnumUtils 要不要都可以~

<dependency>
   <groupId>org.apache.commons</groupId>
   <artifactId>commons-lang3</artifactId>
   <version>3.9</version>
</dependency>

enumClass.getEnumConstants 就是獲取語法糖中的values的方法

package com.wangji92.github.study.other.enums.enhance;


import org.apache.commons.lang3.EnumUtils;

import java.util.Objects;
import java.util.Optional;

/**
 * 枚舉處理工具類
 *
 * @author 汪小哥
 * @date 09-03-2020
 */
public class EnumCodeMsgUtils extends EnumUtils {
    /**
     * 根據code 獲取到當前的枚舉
     *
     * @param enumClass
     * @param code
     * @param <E>
     * @param <T>
     * @return
     */
    public static <E extends Enum<E> & EnumCodeMsg<T>, T> Optional<E> getEnumByCode(Class<E> enumClass, T code) {
        if (code == null) {
            return Optional.empty();
        }
        for (E enumConstant : enumClass.getEnumConstants()) {
            if (Objects.equals(enumConstant.getCode(), code)) {
                return Optional.of(enumConstant);
            }
        }
        return Optional.empty();
    }

    /**
     * 根據code 獲取到枚舉的msg的信息
     *
     * @param enumClass
     * @param code
     * @param defaultMsg 默認返回值
     * @param <E>
     * @param <T>
     * @return
     */
    public static <E extends Enum<E> & EnumCodeMsg<T>, T> String getEnumMsgByCode(Class<E> enumClass, T code, String defaultMsg) {
        Optional<E> enumByCode = EnumCodeMsgUtils.getEnumByCode(enumClass, code);
        if (enumByCode.isPresent()) {
            return enumByCode.get().getEnumMsg();
        }
        return defaultMsg;
    }

    /**
     * 根據code 獲取到枚舉的msg的信息,默認返回爲空
     * @param enumClass
     * @param code
     * @param <E>
     * @param <T>
     * @return
     */
    public static <E extends Enum<E> & EnumCodeMsg<T>, T> String getEnumMsgByCode(Class<E> enumClass, T code) {
        return EnumCodeMsgUtils.getEnumMsgByCode(enumClass,code,"");
    }

    /**
     * 這個是否是一個有效的code
     *
     * @param enumClass
     * @param code
     * @param <E>
     * @param <T>
     * @return
     */
    public static <E extends Enum<E> & EnumCodeMsg<T>, T> boolean isValidEnumCode(Class<E> enumClass, T code) {
        Optional<E> enumByCode = EnumCodeMsgUtils.getEnumByCode(enumClass, code);
        return enumByCode.isPresent();
    }
}

demo

public static void main(String[] args) {
    //獲取msg
    String success = EnumCodeMsgUtils.getEnumMsgByCode(TaskStatusEnumsTwo.class, "success", "");
    log.info("msg:"+success);
	
    //獲取是否存在
    boolean validEnumCode = EnumCodeMsgUtils.isValidEnumCode(TaskStatusEnumsTwo.class, "success");
    log.info("validEnumCode:"+validEnumCode);
	
    //獲取msg的信息
    Optional<TaskStatusEnumsTwo> codeEnum = EnumCodeMsgUtils.getEnumByCode(TaskStatusEnumsTwo.class, "success");
    codeEnum.ifPresent(taskStatusEnumsTwo -> log.info("getEnumByCode:" + taskStatusEnumsTwo.getCode() + taskStatusEnumsTwo.getEnumMsg()));

 }

參考文檔

總結

有上面的方法,如果大規模的使用,對於枚舉來說進行了規範,所有的都一樣這樣對於自己開發來說十分的優好的。不斷的總結、才能不斷提高自己的編碼水平;理論和實踐一樣重要。
更多汪小哥

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章