我須要拍磚 和 看見大家的意見,爲團隊少挖坑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