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