最近在项目中经常遇到软件版本升级后不兼容旧版本的问题,本文根据以往经验,从软件接口设计、实现等方面整理了一些兼容性设计思路。
1. 优化设计
1)接口返回值的定义
有的人喜欢用 0、1 等较小的数字标记返回码或其他一些常量含义,比如我接触过几个项目,使用整型常量 0 作为成功的返回码,在以后的使用中,可能遇到的问题是整型的缺省值为 0,这种情况下逻辑上无法区分没有返回值还是返回了 0,如果某天出现了此类问题,也很隐蔽很难排查。一旦这些常量定义下来,想要修改的代价会非常大或无法修改。所以,在定义这些常量时,要尽可能的考虑到各种可能的情况,不防将数字宽度放大点,预留出扩展空间。
2)版本号处理
初始设计时,应当在消息中保留版本号字段。这样一来,当未来需要做出重大设计改变时,还可以通过引入新的版本号,来实现对旧版本的兼容。当收到消息时,首先通过版本号区分出消息的版本,按照版本号对应的效果处理,从而实现兼容。
3)客户端分类
服务端通常需要接收不同终端发过来的请求,如 APP、微信、网页端、cs 客户端等。设计者不得不考虑的问题是在初版本中功能、实现可能都完全一致,但是不能保证未来有些客户端需要区别对待。
有些设计者会针对不同的客户端同样的功能分开处理、实现多次的设计方式,这种方式固然清晰,相互之间不影响,但带来了代码、工作量的冗余,初版本实现需要写多份,升级修改时也需要修改多处,代码维护效率低,程序员的时间是宝贵的,并且这种方式生成的成果物也是臃肿了很多。虽然如此,也比完全不考虑调用者差异性要进步了很多。
这类问题,加上调用者的类型就能很快解决此问题了,如增加 platForm 参数,定义常量如 “weChat”、“app”、“web”、“cs”、“others” 标记就能轻松解决了,遇到需要区别对待的客户端可能以最快的方式处理。
4)新增参数
在软件开发时,不可避免的会遇到新增接口参数等问题,如果在新版本的接口中暴力的增加了必填参数,就需要所有调用此接口的老客户端都需要重新改动,新旧版本完全不兼容。
对于新增参数,设计者应处理为旧版本非必填参数,结合版本号在新版本可以设置为必填。而对于那些未设计版本号的接口,一定要非必填。
2. 优化实现
1)新增参数
在软件升级开发时,不可避免的会遇到新增接口参数等问题,对于新增参数,处理为非必填参数,可适当增加判空处理,必要时处理为缺省默认值。
如采用 json 传参,针对值获取,有以下几种异常情况需要注意 (适用于 java 开发):
根据上述表格,不难总结出,判空使用 json.get(“param”) 最合适,故可参考如下代码实现:
if(StringUtils.isNotBlank(json.get("param"))) {
param= json.get("param").toString();
}else{
//默认常量
param= DEFAULT_PARAM;
}
2) 参数类型发生变化
如果旧版本参数类型设计得不够合理,或者随着时间的推移,功能的升级,需要改变参数类型时,合适的代码也是有办法做到兼容的,比如:
人脸查询或布控的相似度参数,最初的设计者只要考虑到值范围为 80-90(相似度 80%-90% 之间,传参最小相似度 80,最大相似度 90)这样的情景,采用整型传参,随着算法升级、应用场景更高要求等情况,出现 80.5-90.5 这样的应用需求,代码可这样处理,先转字符串再转换为需要的类型:
Double.parseDouble(json.get(“similar”).toString())
在版本升级时采用上面方式处理之后无论接口传参为整型还是浮点型都能够正常接收,实现版本兼容。
3. 总结
本文总结了一些项目开发中的经验,提出的设计思路和实现方式都很简单,还有其它的设计思路、好的实现方式有待补充。谋事在人,关键在于设计者和开发实现者考虑问题的全面性。
优秀的软件设计会放远目光,考虑到未来的发展方向,预留扩展空间;优秀的代码是基石,就像建房子,设计稿画得再漂亮,材料劣质,也是白白耽误了设计成本。二者结合,高质量的设计,高质量的实现,必能提高效率,降低风险,避免无意义的重复劳动,事半功倍,以此共勉!
原文链接:https://blog.csdn.net/phoenixhdf/article/details/80513075