考拉PC前端重構之路
@(重構)[元件化|拆分]
程式碼重構是一個產品不斷的功能迭代過程中,不可避免的一項工作。所謂重構
,是在不改變程式的輸入輸出即保證現有功能的情況下,對內部實現進行優化和調整。 每個開發人員從業生涯中,或多或少的做過重構工作。小到重寫一個功能函式、業務元件,大到重構一個複雜功能模組或整站重構。
重構是需要花費一定成本和精力的,尤其是一個有各種歷史遺留問題(用的老舊框架或工具)、又糅雜了各種業務邏輯(有些功能邏輯連需求方都未必清楚)、且可讀性及維護性都很差的重要功能模組,比如考拉的下單頁,不動,每次功能迭代的時候都有想撞牆的心,大動,又是不小的工作量,且有一定的風險。當然長痛不如短痛,長遠來看,重構勢在必行。
why 重構
- 設計不合理or全無設計 :原來的實現方式不合理,或者全無模組拆分、元件提取意識的開發模式,純粹的業務邏輯堆疊式開發,會導致功能無法重用,程式碼冗餘,不利於維護。
- 頁面結構與功能實現耦合 :指令碼檔案中夾雜著各種html結構,表現和行為不分離,導致程式碼可讀性和維護性大大下降。(我不會告訴你舊版考拉下單頁的入口指令碼有2000多行,cry~)。
- 程式碼難以理解 :頁面沒有清晰的入口函式,函式呼叫關係混亂,無論改bug還是迭代新功能,面對難以理解的程式碼,開發效率低下。
- 程式碼引起效能問題:不合理的實現方式或者大量無用冗餘的程式碼,引起了明顯效能問題的,需要即時重構優化。
- 框架or類庫更新:前端的技術框架日新月異,在選擇或者淘汰不合適專案的第三方庫的時候,也涉及到重構工作。
when 重構
重構工作其實是隨時都可進行的。當你覺得程式碼可讀性變差、重用性及可維護性降低時,都應該有意識的去做重構。在大部分的專案中,以下將是重構的合理時間點:
- 功能迭代時:當新增一個功能時,發現原有的設計無法滿足新需求,可以考慮重構;在設計功能元件的時候,可以為未來可能的需求預留介面;
- 修復bug的時候:bug產生之後,需要思考是否是不合理的編碼導致的問題而不單單是以解決bug算完事(當然線上重大bug自然以即時修復為第一要務),可以藉助修復bug的契機,把業務邏輯整理清晰,必要時可以找後端配合改介面;
- code Review階段:此階段距離提測時間往往較近,但如果是明顯不合理的實現思路,寧願delay也要重新設計實現;如果前期思考充分,一般不會出現此類情況,大部分是在給其他人review的時候,發現不可理解、可讀性差,這也是需要進一步修改重寫的。
當然在需求緊急的時候,是不適合做重構的。
do重構
以考拉下單頁重構為例。
但凡重構,必須要對已有業務邏輯有較充分的瞭解,評估重構的影響面及可能的風險, 列出基本功能點(也可作為QA的測試迴歸點),保證重構後不要有功能遺漏,不改變現有功能。
如何瞭解已有業務邏輯?
- 跑線上流程;(有些特殊邏輯,模擬困難)
- 對照現有的互動稿;(不斷的功能迭代,可能找不到完整的互動稿)
- 讀懂已有程式碼;(全面瞭解業務邏輯最好的方法,但是耗時)
- 詢問之前的開發者;(如已離職,查詢是否有交接文件之類)
功能模組拆分
在對業務邏輯有充分了解之後,可以進行功能拆分,把可重用的、功能獨立的業務邏輯作為元件或公用模板提取,同時需要考慮元件之間的相互影響。拆分之後,可以多人並行開發,約定好外部呼叫元件的介面即可。
以下是下單頁的功能模組拆分:
根據同步欄位orderType,來確定是普通商品訂單還是賬號充值訂單,並初始化對應的元件;根據同步資訊,非同步獲取下單資訊(含商品資訊及結算資訊);如果是普通商品訂單,服務端會根據使用者所選地址進行拆單,返回拆單後的商品和結算資訊。按功能拆分後,元件及元件的巢狀關係如下:
下單頁目錄結構:
javascript
|——components
| |——address/address.js //地址控制元件
| |——checkcode/checkcode.js //驗證碼控制元件
|——page/order
| |——order_confirm.js //入口指令碼
| |——components
| | |——confirmGoods.js+html //確認商品資訊
| | |——settlement.js+html //結算資訊
| | |——exchangeCoupon.js+html //兌換優惠券
| | |——rechargeInfo.js+html //賬號充值
| | |——invoiceInfo.js+html //發票資訊
| | |——invoice.js+html //設定發票
| | |——bean.html //考拉豆抵扣
| | |——feeList.html //運費稅費列表
| | |——gift.html //贈品資訊
| | |——useCoupon.js+html //使用優惠券
| | |——submitCB.js //提交回撥
| |——widget
| | |——popCoupon.js //彈窗領券複製程式碼
after 重構
- 入口明確,呼叫關係清晰,查詢方便
- 功能實現與結構不耦合,可讀性增強
- 元件化後,有利於功能重用
- 提升了編碼體驗,維護及功能迭代不再感覺煎熬o(^▽^)o
last
重構從來不是一次性行為,是我們需要不斷進行的工作。多人維護以及不斷的功能迭代之後,程式碼多多少少都會有優化的空間,所以在你看到不合理或任何值得重構的地方時,行動起來吧,去優化,不要等到重構的成本更大時再進行,因為那會更痛,不要問我怎麼知道。