前端重構感想

網易考拉前端團隊發表於2017-10-13

考拉PC前端重構之路

@(重構)[元件化|拆分]

程式碼重構是一個產品不斷的功能迭代過程中,不可避免的一項工作。所謂重構,是在不改變程式的輸入輸出即保證現有功能的情況下,對內部實現進行優化和調整。 每個開發人員從業生涯中,或多或少的做過重構工作。小到重寫一個功能函式、業務元件,大到重構一個複雜功能模組或整站重構。

重構是需要花費一定成本和精力的,尤其是一個有各種歷史遺留問題(用的老舊框架或工具)、又糅雜了各種業務邏輯(有些功能邏輯連需求方都未必清楚)、且可讀性及維護性都很差的重要功能模組,比如考拉的下單頁,不動,每次功能迭代的時候都有想撞牆的心,大動,又是不小的工作量,且有一定的風險。當然長痛不如短痛,長遠來看,重構勢在必行。

why 重構

  • 設計不合理or全無設計 :原來的實現方式不合理,或者全無模組拆分、元件提取意識的開發模式,純粹的業務邏輯堆疊式開發,會導致功能無法重用,程式碼冗餘,不利於維護。
  • 頁面結構與功能實現耦合 :指令碼檔案中夾雜著各種html結構,表現和行為不分離,導致程式碼可讀性和維護性大大下降。(我不會告訴你舊版考拉下單頁的入口指令碼有2000多行,cry~)。
  • 程式碼難以理解 :頁面沒有清晰的入口函式,函式呼叫關係混亂,無論改bug還是迭代新功能,面對難以理解的程式碼,開發效率低下。
  • 程式碼引起效能問題:不合理的實現方式或者大量無用冗餘的程式碼,引起了明顯效能問題的,需要即時重構優化。
  • 框架or類庫更新:前端的技術框架日新月異,在選擇或者淘汰不合適專案的第三方庫的時候,也涉及到重構工作。

when 重構

重構工作其實是隨時都可進行的。當你覺得程式碼可讀性變差、重用性及可維護性降低時,都應該有意識的去做重構。在大部分的專案中,以下將是重構的合理時間點:

  • 功能迭代時:當新增一個功能時,發現原有的設計無法滿足新需求,可以考慮重構;在設計功能元件的時候,可以為未來可能的需求預留介面;
  • 修復bug的時候:bug產生之後,需要思考是否是不合理的編碼導致的問題而不單單是以解決bug算完事(當然線上重大bug自然以即時修復為第一要務),可以藉助修復bug的契機,把業務邏輯整理清晰,必要時可以找後端配合改介面;
  • code Review階段:此階段距離提測時間往往較近,但如果是明顯不合理的實現思路,寧願delay也要重新設計實現;如果前期思考充分,一般不會出現此類情況,大部分是在給其他人review的時候,發現不可理解、可讀性差,這也是需要進一步修改重寫的。

當然在需求緊急的時候,是不適合做重構的。


do重構

以考拉下單頁重構為例。

但凡重構,必須要對已有業務邏輯有較充分的瞭解,評估重構的影響面及可能的風險, 列出基本功能點(也可作為QA的測試迴歸點),保證重構後不要有功能遺漏,不改變現有功能。

如何瞭解已有業務邏輯?

  • 跑線上流程;(有些特殊邏輯,模擬困難)
  • 對照現有的互動稿;(不斷的功能迭代,可能找不到完整的互動稿)
  • 讀懂已有程式碼;(全面瞭解業務邏輯最好的方法,但是耗時)
  • 詢問之前的開發者;(如已離職,查詢是否有交接文件之類)

功能模組拆分

在對業務邏輯有充分了解之後,可以進行功能拆分,把可重用的、功能獨立的業務邏輯作為元件或公用模板提取,同時需要考慮元件之間的相互影響。拆分之後,可以多人並行開發,約定好外部呼叫元件的介面即可。
以下是下單頁的功能模組拆分:

enter image description here
enter image description here

根據同步欄位orderType,來確定是普通商品訂單還是賬號充值訂單,並初始化對應的元件;根據同步資訊,非同步獲取下單資訊(含商品資訊及結算資訊);如果是普通商品訂單,服務端會根據使用者所選地址進行拆單,返回拆單後的商品和結算資訊。按功能拆分後,元件及元件的巢狀關係如下:

enter image description here
enter image description here

下單頁目錄結構:

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

重構從來不是一次性行為,是我們需要不斷進行的工作。多人維護以及不斷的功能迭代之後,程式碼多多少少都會有優化的空間,所以在你看到不合理或任何值得重構的地方時,行動起來吧,去優化,不要等到重構的成本更大時再進行,因為那會更痛,不要問我怎麼知道。

相關文章