通用状态码设计

背景

在企业中,一个对外发布的产品一般会涉及到好几个部门、不同人员开发的系统。
每个部门甚至每个人开发的系统的返回码体系可能都是不一样的,比如:

  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";
    }
}

拥有了统一的返回码,那么设计一个通用的响应消息数据结构也变得比较轻松了。


通过这个例子,让我再次感受到类设计和接口设计上的思维差异:

  • 接口更多的是用来描述行为(能干什么),不关心具体的数据以及实现逻辑;
  • 而类设计则用来描述实体之间层次结构以及内部的数据和状态(是什么)。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章