通用狀態碼設計

背景

在企業中,一個對外發布的產品一般會涉及到好幾個部門、不同人員開發的系統。
每個部門甚至每個人開發的系統的返回碼體系可能都是不一樣的,比如:

  1. A系統把系統返回碼都放在SystemAResultCode的枚舉類中
  2. B系統則把系統返回碼都放在SystemBResultCode的枚舉類中
  3. 等等

系統間不同的返回碼會造成:

  1. 無法設計通用響應數據結構。在rpc調用場景,這一點很重要;
  2. 無法互操作。當需要對返回碼組織層級關係時,需要直接操作被調用方返回的返回碼。

目標

  1. 可擴展:隨着業務發展,返回碼肯定處於一個膨脹的過程。設計時給各個業務系統保留擴展能力;
  2. 互聯互通互操作:系統之間的返回碼要能夠互通。我能夠讀取你的返回碼,你也得認我的返回碼;
  3. 能夠定義基礎行爲:如統一加系統、業務標識或者定義返回碼之間的繼承邏輯。

實現

系統中的返回碼一般都會設計成一個枚舉類,枚舉類有天然的好處:

  1. 集中管理,系統中有哪些返回碼一目瞭然
  2. 枚舉實例可以通過名稱進行自解釋
  3. 枚舉實例被final修飾不能被重新賦值,避免運行過程中被修改
  4. 等等

但是這裏有一個問題:枚舉不能被繼承
這個語法規範直接把設計一個父枚舉,各個系統去繼承該父枚舉的想法扼殺在搖籃中。

有沒有其他辦法了呢?答案是有的:

利用枚舉可以實現接口的特點,定義一個返回碼行爲接口,各個系統的返回碼枚舉類實現該接口即可。

甚至可以利用Java8的特性,在接口中定義default方法來描述返回碼的組織關係,如:

  1. 隔離系統間的返回碼,避免重複;
  2. 定義返回碼之間的繼承行爲等。

example

/**
 * 各個應用方應當實現本接口,以實現自定義的返回值
 * @see DefaultResultCode
 *
 * @author liumian  2020/3/2 2:22 下午
 */
public interface ResultCode {
    /**
     * 獲取返回碼
     *
     * @return resultCode
     */
    String getCode();
    /**
     * 獲取簡單的說明
     *
     * @return resultMsg
     */
    String getMsg();
    /**
     * 獲取系統碼,用於區分系統
     *
     * @return 系統碼
     */
    String getSysCode();
    /**
     * 獲取全局的返回碼,系統間不會重複
     *
     * @return 全局返回碼
     */
    default String getFullCode(){
        return getSysCode()+"-"+getCode();
    }
}
public enum DefaultResultCode implements ResultCode{
    /**
     * 成功
     */
    Success("000001","success");
    private String code;
    private String msg;
    DefaultResultCode(String code, String msg) {
        this.code = code;
        this.msg = msg;
    }
    @Override
    public String getCode() {
        return code;
    }
    @Override
    public String getMsg() {
        return msg;
    }
    @Override
    public String getSysCode() {
        return "default";
    }
}

擁有了統一的返回碼,那麼設計一個通用的響應消息數據結構也變得比較輕鬆了。


通過這個例子,讓我再次感受到類設計和接口設計上的思維差異:

  • 接口更多的是用來描述行爲(能幹什麼),不關心具體的數據以及實現邏輯;
  • 而類設計則用來描述實體之間層次結構以及內部的數據和狀態(是什麼)。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章