我须要拍砖 和 看见大家的意见,为团队少挖坑javascript
终端调用(PC端、移动端APP、微信端、Web端)-->控制器 或 接口-->实际的业务处理-->控制器 或 接口-->终端作出相应处理(控制器多是渲染对应页面; 接口返回 JSON数据)php
先后端数据格式约定为 JSON格式以下:html
{ code: "00000", // 状态码 msg: "操做成功!", // 提示信息 data: {} // 数据 }
注:"00000":业务成功状态码;非"00000"都为业务失败。
为了防止服务器端状态码泛滥成灾,code能够为"",这时 msg 里面则是相应的错误信息,只为给用户提示。前端
项目开发完毕,测试人员去测试,提以下Bug:java
若是用户未登陆,进我的中心,提示用户未登陆,而后会去登录view;而在下单页,提示用户未登陆,却没有去登录view。web
而后前端童鞋开始去修复该问题,查出以下问题:面试
{ code: "00008", msg: "用户未登陆,请登陆", data: [ ] }
{ code: "", msg: "用户未登陆,请登陆!", data: [ ] }
而后前端童鞋对服务器端童鞋讲,这里你应该返回给我code: "00008"
,我这边一看 code便知是用户未登陆,就能够作出相应的操做,这里你只返回提示信息,我这边很差作更加细腻的操做。ajax
而后,后端童鞋开始尝试给该地方添加上 code。
开始着手修改代码:
首先找到接口方法里面发现以下 demo:后端
php$order = kernel::single('sysapi_ecoupon_order')->create($params, $msg); if (!$order) { return array('code' => '', 'data' => array(), 'msg' => $msg); } return array('code' => '00000', 'data' => $order);
改方法返回array(); 在外部统一入口、出口处再返回 JSON出去。api
sysapi_ecoupon_order
phppublic function createNew($params, & $msg) { // 获取用户信息 $member_info = app::get('b2c')->model('members')->get_current_member(); if (empty($member_info)) { $msg = app::get('ecoupon')->_('用户未登陆,请登陆!'); return false; } // 继续下面的业务处理 }
接口调用的kernel::single('sysapi_ecoupon_order')->create($params, $msg);
这里面作实际的业务处理,错误信息是经过 $msg 向上传递出去,外部没办法经过 $msg 获知对应的 code。而后给前端童鞋讲这种状况没办法返回 code给你。
前端就只能经过判断 msg的方式来修复该问题
而后写了以下 demo:
javascriptif("用户未登陆,请登陆!" == data.msg) { // 用户未登陆,去登陆 // ... }
而后提交,测试,经过,上线,N天后
有人跑过来说:下单页 与 我的中心的提示有点不一样,貌似多了个 "!"。(举例而已,更多的多是提示不友好、错别字等状况)
而后后端同窗修改成 $msg = app::get('ecoupon')->_('用户未登陆,请登陆');
提交,测试不经过,前端同窗再修改成if("用户未登陆,请登陆" == data.msg)
,提交,测试经过
// 如此反反复复
终究有一天:产品、测试,前端、后端混战了一场。N人,卒.....
最终先后端得出结论:要想对用户实现更加友好的体验,先后端数据必须有个标识具备惟一性
,不变性
。而如今用的 msg却不具有,仍是得用 code。而且这里先后端极度耦合
msg。
后端童鞋回来继续修改代码,开始着手给这里添加上相应的 code。
开始思考该怎么添加 code,如今的问题是 create( ) 方法多是其余童鞋开发,内部返回的提示信息,我这边是调用者,不能肯定方法内部到底会返回什么提示信息,无解。
突然,有一天想到,我在调用该方法以前检查下用户有没有登陆就OK了,而后开始写以下实现:
public function create($params) { $member = app::get('b2c')->model('members')->get_current_member(); // 登陆验证 if (empty($member)) { return array('code' => '00008'); } $msg = ''; $order = kernel::single('sysapi_ecoupon_order')->create($params, $msg); if (!$order) { return array('code' => '', 'data' => array(), 'msg' => $msg); } return array('code' => '00000', 'data' => $order); }
呵呵,好机智的少年。
而后告诉前端,这里能够返回 code了,前端愉快的删掉原来那坨判断 msg的代码,而在 ajax请求的地方统一判断 code就能预知用户未登陆,作出相应的操做。
经测试,上线。一切又回到了美好时光。
随着时光的流逝,业务的增长,后端童靴发现Order类里面以下 demo:
phppublic function create($params) { $member = app::get('b2c')->model('members')->get_current_member(); // 登陆验证 if (empty($member)) { return array('code' => '00008'); } // 实际业务处理.... } public function getOrderList($params) { $member = app::get('b2c')->model('members')->get_current_member(); // 登陆验证 if (empty($member)) { return array('code' => '00008'); } // 实际业务处理.... } public function getOrderDetail($params) { $member = app::get('b2c')->model('members')->get_current_member(); // 登陆验证 if (empty($member)) { return array('code' => '00008'); } // 实际业务处理.... } // ...
这都是什么玩意............ 而后开始封装,稍微好了点
又过了一段时间,有人过来讲建立订单还须要优化体验,
点击建立订单提示以下:
这时,前端童鞋告诉后端童鞋,商品下架的时候,你也应该返回一个状态码。
后端童鞋开始打算添加 code,发现以下 demo
phpkernel::single('sysapi_ecoupon_order')->create($params, $msg);
这里的提示信息是 $msg 返回的,用户登陆外部能够提早检测,这里的商品可否购买要实现添加 code也须要提早检测,未来要是须要添加类是功能岂不是...... 每须要一个精确的 code返回出去,这里就须要添加检测,这里代码将会变得没法直视。
何况这里本该在业务里面检测,一切不那么友好起来了。
再次思考,代码写的不爽了,必定是哪里不对
开始怀疑 public function create($params, & $msg) { }
这里不该该是经过 & $msg
来做为 调用者与 被调用者之间的 错误信息通讯约定,一切的问题都出在了这里。错误消息向上传播的约定不合适
若是这里约定的是 code做为错误向上传播一切的问题即将不复存在。在调用业务方法以前的检测代码就均可以去掉了,代码简约,一切又美好起来。
接下来继续思考,使用 code做为业务处理失败消息传递问题又来了
public function create($params, & $msg)
,怎样更加友好的替换成 code惟一性
的标识(code 比 msg 对国际化的实现更加容易)可是并不能直接展现给用户,那么就须要定义每一个 code 的表明的意义 与 对应的提示信息。那么问题来了,code 应该已怎样规范来定义所表明的含义再来看以下经常使用的两种方法定义:
public function create($params, & $msg)
public function create($goodsId, $num, & $msg)
第一种方式,参数经过一个 $params数组传递过来,方法内部在把错误提示放到 $msg中。
第二种方式,按基本类型分别传递单个参数
这里有以下问题:
Java里面方法参数已对象的方式传递能够借鉴
)& $msg
真的合适吗,若是是第二种方式定义的方法,之后扩展个 $phone 该如何处理?public function create($goodsId, $num, & $msg, $phone='')
这样么?怎么看怎么蛋疼phppublic function create($goodsId, $num) { if ( ? ) { // 返回状态码 return '0001'; } if ( ? ) { // 返回状态码 return '0002'; } // 建立订单 // ... // 返回订单信息 return $order; }
看似实现了,可是方法调用者,怎么调用怎么蛋疼,一会返回状态码,一会返回订单信息,彻底两种类型。
得出如下结论:
再次思考,最终从 Java里面想到了一点思路(幸亏是 Java出身。疑问:为什么面试的时候 Java的工做经验都不算在 PHP工做经验里呢,并无所以而加分)
因我的工做时间、项目经历很少、归根结底经验不足。如今将该方案写下来,还望有经验的大神拍砖,以避免给团队挖坑,以上 $msg 就是 N久之前埋下的坑。
该文章发布在本身站点地址:http://www.webdevs.cn/article/91.html