01

假如现在有一个接口,别人调用送过来的请求报文中有个字段叫 vipType,对服务方来说,假设这个数据只有3种类型:1-穷逼VIP ,2-普通VIP,3-尊贵VIP。

那么问题来了,这个对应的关系往往只有你自己知道,所以其他系统就得来问你该送什么?如果没有沟通好,或者沟通异常,就会乱送。

明明是数字,结果送了一个“VIP1”过来,系统入库直接报错:Data too large... ...

多么熟悉的场景,多么熟悉的味道?

但是,这根本难不住我们聪明的大脑,设置数据类型啊,vipType就是int类型,别的类型一概不收。

OK,就这么办,比如代码是这样的:

可是,这样虽然类型控制住了,却没有控制范围?对方非要传个-1过来,你一点办法都没有。于是就开始助讯通扯皮。

而且,你虽然写了注释,但是调用谁知道你的码值对应关系呢?还是只能你主动坦白,助讯通告知。或者查询对应的接口文档才会知道。

可是万一哪天码值改了,文档没有更新呢?

比如,我们可以学习一下不要脸的百度网盘,再加一个SVIP。

很多情况下,我们只是数据库加了字段,然后主动助讯通告知调用方,口口相传,若无必要乃不传之秘。

而且,假如我们的代码是这样的,很多地方都用了,那么90%的情况下很少有人会全局搜索代码,去一个个加注释。

最终,vipType的码值到底如何,于云雾一般,可远观而不可亵玩。

为了控制范围,甚至写出了这样的代码:

if(user.getVipType() > 4 && user.getVipType() < 1) {

    throw new Exception("VipType 错误!");

}

乍一看没有任何问题,可是假如20个地方需要用到user对象,万一哪天改了,是不是得改20个地方?

一个最快速的解决方案,就是写一个公共方法,每个地方都调用一次。当然,也可以选择不做任何判断,真遇到问题再说,多大点事儿。

02

过了一段时间,又有问题了,因为代码已经改了很多版,注释也基本没人写了。

新人接手代码,除了一脸懵逼还是一脸懵逼,憋了半天终于忍不住问同事,这个vipType的数据字典在哪里啊??

“哦,你去查下xxxDataDiC表,那里面是最准的!”

... ...

于是,你觉得不难再这样下去了,有了,我干嘛不用常量类??

像这种常用的数据字典,放在常量类里面不要太完美,最起码别人能查到这个是啥意思。

于是,就有了一个xxxConstances

public class MyContances {


    
    public static final String VIP_TYPE_BEGGER = "1"; //穷逼VIP

    public static final String VIP_TYPE_NORMAL = "2"; //普通VIP

    public static final String VIP_TYPE_ZUNGUI = "3"; //尊贵VIP



}

下次遇到这种情况,如果有新同事问你,你终于可以潇洒的说:“有常量类,你自己不会看啊!”

问题仿佛终于得到了解决,但是却依然无法控制对方乱送值的问题。除非你用一大堆的if else去判断,又或者干脆不做判断。嗯,约定大于配置,再次回到了口口相传的步骤。就算对方真的乱送,也是对方的问题,关我啥事儿?

03

又过了一段时间,矛盾涌现,比如真的加了SVIP,并且某个业务要求你根据不同的VIP等级设置不同的优惠折扣:

VIP

折扣

最多

1

9.5

20元

2

9.2

50元

3

8.8

100元

4

8.5

120元

太简单了,直接if else不就行了。

if(String.valueOf(user.getVipType()) .equals( MyContances.VIP_TYPE_BEGGER) ){

    System.out.println("9.5折,最多20元!");

}else if(String.valueOf(user.getVipType()) .equals( MyContances.VIP_TYPE_NORMAL)) {

    System.out.println("9.2折,最多50元!");

}

下次有新的需求过来,我TM直接反手就是一个else if,而且即便是新人接手代码,也不必担心看不懂码值的问题了。

代码到这一步,我不禁感叹,多么优雅,可读性真的强,原来我也是个小天才。

04

又过了一段时间,随着业务越来越复杂,码值越来越多,就会出现一个问题。就是用到vipType的地方,每次有改动,你就不得不去修改所有的地方。万一有个地方漏了,就GG了。

这似乎没有办法了,难不成还能不写if else?

还别说,真有。虽然用常量类很好,但是有个问题,常量类里面的变量,说到底就是一个基础的类型!

我们为什么不去丰富一下呢?

比如,不用常量类,单独设置一个VipType的常量类呢?

public abstract class VipTypeEnum {


        private String code;
        
        private String value;
        
        private String desc;


        //防止别人瞎几把new,直接单例走起
        private VipTypeEnum() {


        }


        private VipTypeEnum(String code,String value,String desc) {
        
                this.code=code;
        
                this.value=value;
        
                this.desc=desc;

        }


        //抽象的打折方法
        
        protected abstract void discount();


        public static VipTypeEnum of(int vipType) {
        
                if(String.valueOf(vipType).equals("1")){
        
                return VIP_TYPE_BEGGER;

        }


        //其他代码省略
        return null;

        }


        public static final VipTypeEnum VIP_TYPE_BEGGER=new VipTypeEnum("1","VIP_TYPE_BEGGER","穷逼VIP") {
        
        
        @Override
        
        protected void discount() {
        
                System.out.println("9.5折");
        
                }

        };


//其他几个也类似

// ... ...

                //省略getters,setters


        }

于是乎,判断的地方只需要写成这样:

也就是说,不管你业务怎么变,一个VipTypeEnum类,给你全部搞定!

如果业务增加怎么办? 在VipTypeEnum类里面做增量,再添加一个新的类型,实现抽象方法即可。

其实这个就是枚举,或者说,是JDK1.5以后的枚举类型的底层设计。

嗯,思路有了,优化方案也有了,敢不敢这样优化,就看你的胆量了。额,我反正不敢。哈哈哈,反手一个else if不香吗?

果然还是逃不过真相定律啊。

posted on 2022-05-01 23:07  剽悍一小兔  阅读(8)  评论(0编辑  收藏  举报  来源