前言
上个月开始和同事一起做一个为期一个月的项目。期间同事看了我的代码,给我投来了一个奇异的眼神,问道“你的代码没有错误码吗?我调你的方法,我怎么知道成功与否呢?”,今天我就这个话题来讨论一下为什么系统内部调用时不需要封装请求结果,出错直接抛出异常就好。
核心争论点
系统的内部调用是否需要封装错误码以及请求返回结果。换句话说,我同事认为一个成功的系统调用需要像下面这样返回数据对象(这里只是以json作为示例,并不代表我们调用的结果是json)。
{
"code": 200,
"success": true,
"msg": "",
"data": {}
}
而一个失败的系统调用是否又需要像下面这样返回。
{
"code": 500,
"success": false,
"msg": "error message",
"data": {}
}
使用结果类
这里我觉得可能她是受《阿里巴巴开发手册》里面的一条关于 RPC 调用规范的影响
跨应用间 RPC 调用优先考虑使用 Result 方式,封装 isSuccess()方法、“错误码”、“错误 简短信息”;而应用内部推荐异常抛出。
说明:关于 RPC 方法返回方式使用 Result 方式的理由:
1)使用抛异常返回方式,调用方如果没有捕获到就会产生运行时错误。
2)如果不加栈信息,只是 new 自定义异常,加入自己的理解的 error message,对于调用端解决问题
的帮助不会太多。如果加了栈信息,在频繁调用出错的情况下,数据序列化和传输的性能损耗也是问题。
系统内部调用要使用异常
文中也提到,系统内部调用还是应该通过抛出 异常 的方式,而不是用 Result 方式来返回错误结果。 (这里的 Result 方式就是上文我们提到的,使用结果类来封装请求结果)。
在系统内部使用 异常,相对于使用 Result 方式来说有个非常明显的优点–在使用异常时,不需要对调用成功与否进行判断。
如果调用失败直接抛出异常,调用者处理这个异常就好。
看到这里大家可能有疑惑,这么简单的问题为什么还需要和同事讨论?
我认为有这个讨论的根源问题在于每个人开发习惯的不同。方法调用时同事更喜欢使用 Result 方式来处理,而我更喜欢使用 异常 的方式。
其实,我这个时候做个让步也没什么,毕竟只有提供给她的部分函数需要按照这个方式,改动量不大。但是最近我在读
Sonmez 的《Soft Skills》,我对里面提到的一个观点很有感触,或许是受这个观点潜移默化的影响,我觉得有必要坚持我的观点。
作为一名软件开发人员,你经常面临许多困难和挑战,技术和道德两个方面都有。如果你想成为专业人士,你必须要在两种情况下都做出正确的选择
结束语
这里不得不提到逍遥子和马老师老是挂在嘴边的一句话,“要坚持难却正确的事”。不过,在文章最后有个忠告,在和同事争论的时候要充分说明你的理由,
切忌说 “这是 XXX(某个有名的人或者权威)说的”、“这是 《xxx》 书上讲的”、“大家都是这样做的”等,这些话隐藏着 “你只是一个盲目跟随的人,并不理解为什么要这么做” ,
会让同事认为你的思考不够, 更加难说服对方。
扩展
在《阿里巴巴java开发规范》关于 RPC 调用的描述中,对使用 Result 方式的解释主要是围绕 Client 端的理解成本和性能。
这里我进行补充下。目前很多公司的服务端开发语言越来越丰富,目的都是期望发挥不同编程语言的优势。
当不同编程语言之间通过 服务治理框架 互联和互通时,不同编程语言之间的差异,可能会对调用结果的产生一些不可控的影响。
比如:异常 这个东西并不是所有语言中都有,当服务端返回异常,当 Client 端的编程语言中没有 异常 的情况下,
服务治理框架会对响应结果中的 异常 进行转换,转换结果并不可控,会对服务调用方造成非常大的困扰(问题排查、异常情况处理)。
所以,为了保证应用在多编程语言环境下的 鲁棒性,对 RPC 调用结果使用 Result 方式很有必要。