重構 - 代碼整潔之道

做者簡介 新茗 螞蟻金服·數據體驗技術團隊前端

前言

以前也介紹過咱們團隊的前端項目從零開始經歷8個月迭代業務代碼10萬行(僅爲產品長期規劃需求的20%),至今仍然在不斷迭代的過程。git

團隊成員除了設計好的架構來管理這種複雜度極高的前端應用,還開始補充設計模式以及重構方面的知識,目的是爲了讓項目代碼在不斷迭代的過程當中優化項目代碼,保持代碼的新鮮度,魯棒性,可維護性… 讓後續加入的團隊新人也能夠快速加入咱們的產品開發中程序員

PS: 無論對於何種語言,重構都是軟件開發過程當中不可或缺的一部分。若是已經瞭解重構的基礎,能夠直接跳往至文章後面的重構案例部分。github

重構背景

「若是尿布臭了,就換掉它」。設計模式

  • 隨着業務需求的不斷加入,代碼隨着時間的推移變得愈來愈糟。
  • 這其中可能包括如下壞味道(僅列舉):
    • 重複的代碼
    • 過長的函數
      • 遵循一條原則: 每當感受須要註釋來講明什麼的時候,能夠嘗試將須要說明的東西寫進一個函數中
    • 冗贅類
      • 當子類沒有作足夠的工做的時候,或者說在可見的預期內,不會有新的狀況出現,考慮將類內聯化。
    • 過長的類
      • 這種狀況容易出現冗餘代碼。好比若是類內出現了多個變量帶有相同的前綴或者後綴,這意味着你能夠考慮把他們提煉到某個組件內,或者考慮這個組件是否能夠成爲子類,使用提煉類的手法來重構。

什麼是重構

咱們回過頭來看一下"什麼是重構"架構

  • 不改變軟件可觀察行爲的前提下,改善其內部結構函數

  • 以提升理解性和下降修改爲本工具

    摘自《重構 - 改善既有代碼的設計》(下面簡稱《重構》)
    複製代碼

什麼時候重構?

咱們須要明確的一點是: 重構不是一件應該特意撥出一段時間來作的事情。重構不是目的,可是重構能夠幫助你把事情作好。學習

事不過三,三則重構開發工具

  1. 重複性工做,既有的代碼沒法幫助你輕鬆添加新特性時
  2. 修補bug時,排查邏輯困難
  3. code review 可讓他人來複審代碼檢查是否具有可讀性,可理解性
  4. 太多的代碼無註釋,已然連本身都沒法快速理清代碼邏輯

重構的衡量指標

  • 數量: 代碼的行數
  • 質量: 代碼複雜度,耦合度,可讀性,架構依賴複雜度等
  • 成本: 花費的時間
  • 回報(成果): 支持後續功能的快速疊加,解決現有因代碼設計問題沒法優化的矛盾等

抓重點 抓重點啦

說了這麼多廢話,其實你們都明白沒有與實踐結合的理論都是空虛的。

可是 重構設計模式同樣,也是須要一個"學習——領悟——突破"的過程。第一步的學習讓你瞭解基本的重構手法,第二步的實踐勾起你對重構手法的回憶以及重溫應用,第三步的應用以及實踐經驗激發你的思考,領悟以及總結,以至於靈活運用。

但凡是人,老是在不斷學習,不斷溫習,以達到具體場景具體應用,靈活自如。 重構是一個很大的話題,《重構》做者本人也是經歷了N多的項目,以及多年的經驗才總結出來的重構技巧。

重構技巧

《重構》一書做者總結的重構手法實在是太多了,只能經過圖片來展現一下全部做者總結的重構列表。
具體的補充,你們能夠看看《重構》一書。

重構的實踐

做者推薦的一種作法:

  1. 隨機挑選一個目標 先給本身選擇一個目標(譬如「去掉一堆沒必要要的子類」),而後朝着目標前進,每一步走得小而堅決
  2. 沒把握就停下來 當你沒法證實本身所作的一切可以保證原有程序的邏輯和語義時,請你停下來思考:既有的重構是改善了仍是毫無成果須要撤銷。
  3. 保證每次重構後的測試都能正常跑通

做爲開發者, 應當把重構做爲開發的一部分,一邊開發一邊重構。在快速堆疊代碼,實現基本需求功能的基礎上,寫好測試用例,保證功能不變,逐步重構。
這也是咱們團隊要求每一個人都掌握重構這門必備技能的緣由。優秀的程序員應當儘可能避免低質量的代碼。

重構案例

故事場景

  1. 有三種類型的電影,顧客能夠進行租賃
  2. 租賃規則
    1. 價格計算規則:
      普通片兒 —— 起步價2¥,超過2天的部分天天每部電影收費1.3元
      新片兒 —— 天天每部3元
      兒童片 —— 起步價2¥,超過3天的部分天天每部電影收費0.8元
    2. 積分計算規則:
      每借一部電影積分加1,新片每部加2

原始代碼

程序結果:(請保證重構後結果不變~)

  • 類圖

有興趣的能夠先看看原始代碼,考慮一下其中的原始對象關係,再行考慮如何重構代碼。 原始代碼實際上是有不少問題能夠挖掘的,下面是咱們的討論整理:

  • 劃分職責關係,遵循單一職責原則
    • statement打印帳單函數承擔了不少功能,包括收費計算,積分計算以及結果展現等等
      • 解法1: 6.1 Extract Method(提煉函數) —— 最經常使用的重構手法
      • 解法2: 9.1 Decompose Conditional(分解條件表達式)
    • 用戶類中承擔了不屬於它的職責,包括:收費規則、積分規則。這些職責應該是屬於電影類型的。
  • 整理清楚其中的業務邏輯,好比收費規則和積分規則 - 見故事場景
  • 不要直接訪問對象的數據。容易發生其餘對象改變該對象的數據,而擁有該數據的對象卻一無所知。
    • 解法:8.10 Encapsulate Field(封裝字段手法) —— 使數據和行爲想分離
  • 重構不該該被外界所感知,保證testcases依然可行

部分重構

這裏爲了更好的展現重構的手法,使用TS,根據上面的討論進行了部分重構,重構的方式實際上是根據業務將來的擴展方向而定,並無最優解,有興趣的能夠加入咱們,拋出你的看法~

  • 重構後的類圖關係

基本技巧

  • 小步前進,頻繁測試(保證足夠的測試來支持你的重構行動)
  • 使用智能開發工具(好比VSCode右鍵能夠將過長的函數代碼拆解函數化)

推薦書籍

重構實際上是一件須要長期投入,而且投入產出比很高的事情。對重構感興趣的同窗能夠關注專欄或者發送簡歷至'tao.qit####alibaba-inc.com'.replace('####', '@'),歡迎有志之士加入~

原文地址:github.com/ProtoTeam/b…

相關文章
相關標籤/搜索