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不香吗?
果然还是逃不过真相定律啊。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)