代码传递信息的方式探究
Posted 雨中漫步,惟情而已
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了代码传递信息的方式探究相关的知识,希望对你有一定的参考价值。
相信在使用MVC思想进行编程的猿类们对该规约不陌生:controller层只用来做分发,具体的业务逻辑应当放在服务层(service或manager)。
上述的规约的核心其实是:代码模块化,每个模块各司其职。
当然,实际上想要完全执行上述标准有一定的困难,个人觉得主要有如下几点原因:
- 多人开发,各人的编程水平、想法不一致,对代码控制的范围划分不一;
- 因为将本来一块的代码划分成了多块,增加了编程的复杂性(但实际上简化了后期的维护以及拓展,更清晰),比如需要规划分成多少块合适,这样,部分猿类选择了偷懒~;
- 信息传递不方便;
本文主要探究第三点,那我所说的“信息传递不方便是”什么意思呢?举个例子:
客户通过请求来获取账户的信息,假如所有的业务逻辑都放在controller层中的一个请求方法中,那么如果请求的参数不满足要求,可以直接返回给客户哪些地方不满足要求,比如你提供的用户id是别人的,权限不足等等。
但如果controller只是用来分发业务,具体的业务实现都是放在服务层,那如果请求的参数不满足要求时,服务层该怎样把诸如“你提供的用户id是别人的,权限不足”这样的具体信息返回给controller层呢?不管方式具体是怎样,无疑都会增加一道门槛,这也就是我所说的“信息传递不方便”。
不过,虽然有这种不便之处,但相对于“各个模块只做各自的事情”所带来的优势来说简直不值一提,最直接的就是代码复用,因此我们需要解决“信息传递不方便”这样的问题,而不是因噎废食。
笔者工作时间不算太长,对于上述问题的解决方案,接触的主要有两种:
- 使用统一的结果类来携带信息。比如,封装一个Result对象,该类中定义好信息-message、具体数据-data等属性,每一个小模块(或方法)都返回Result对象,这样既能保证返回方法的结果,也能携带对应的信息;
- 使用异常抛出信息。这种方式不需要有封装好的Result对象,如果方法返回的是boolean,那就是boolean,如果需要传递信息出去,那么抛出自定义异常,异常中携带信息;
我们来对比一下上述两种方案,方案一的优缺点如下:
- 优点:无论方法是否顺利执行,你都可以传递信息,比如,某条信息入库成功,方案二只能根据返回结果是否为boolean自行给定信息;
- 缺点:每个方法都需要处理封装的Result对象,大大增加了方法的复杂度,而且不便于重构,假如Result对象被弃用了,想换成ResponseResult对象,那么需要更改大量的代码;
方案二优缺点如下:
- 优点:方法只做自己范围内的事情,不需要处理其他,如方案一的Result对象,与其他代码的耦合性降低;
- 缺点:只能在代码不能正常(所需条件不满足或异常)时,传递信息,顺利时不能传递;
貌似方案一和方案二的优缺点正好相反,但实际不是,先不说方案二的优点要比其缺点好上多少,单说方案二的缺点,其实都不能称之为缺点,因为个人觉得在方法中我们自定义的信息就应当是有问题的时候才需要传递,正常的时候正常返回对应的结果就好了。
这样其实更符合我们的理解,比如说去银行取钱(调用一个方法),如果顺利那就是银行给你需要的金额(获取结果),具体你想怎么表达你的喜悦自行决定就好了(给客户返回的对应信息),银行在给你钱的过程中完全可以不说话,只有在银行钱不够无法给你提供正常的结果时银行才需要向你传递“钱不够”这样的信息,所以从某种方面说,方案一的优点只是一种副作用。
而且最主要的是代码的耦合性,也就是方案二的优势,这种优势完全不是方案一优势所能比拟的!
所以在方法传递信息时,更加推荐第二种方案,这种方案可以在达到目的的同时,减少大量耦合性代码,并且足够优雅!
不过,这里还是有个小小的问题,抛出的异常是否需要区分呢?
直接给出我的想法,需要进行区分。
还是以客户发送请求来获取账户信息为例,假设客户发送的用户id不是自己账户的(攻击),那么在controller层转给服务层某个校验权限方法后,该方法查询数据库发现权限不对,抛出异常返回给调用方法“权限不足”的错误信息,服务层继续抛出该异常,controller层接收后返回对应的错误信息,这样的流程没有问题。
但还有一种情况,在校验方法查询数据库时出现了数据库异常,按照上一种情况,会抛给服务层调用方法,服务层继续抛出该异常,controller层返回给客户错误信息,如数据库连接失败,这种情况明显就不合理了,服务器内部的错误信息不应当显示给客户。
因此,对于抛出的异常我们可以基本分成两类,一种是自定义的业务异常,另一种就是其他异常,controller层或者服务层接收到自定义业务异常后选择将对应的异常信息展示给用户,如果不是,那么可以统一返回“系统异常,请稍后重试”的信息,避免服务器内部错误外现,不仅影响客户体验,也容易暴露网站安全问题。
ps:以上是我对传递信息的方式的探究,因水平限制,难免会有问题,如发现有什么不妥或者有更好的建议,还请各位不吝赐教!
以上是关于代码传递信息的方式探究的主要内容,如果未能解决你的问题,请参考以下文章