系統重構筆記

重構概念

在不改變軟件可觀察行爲的前提下,對軟件內部結構的一種調整,提升其可理解性,下降修改爲本。git

重構節奏

測試、小修改、測試、小修改......正是這種節奏讓重構得以快速安全而安全的前行。程序員

構築測試體系

若是想要重構,咱們必須擁有一個良好的測試環境。編寫優良的測試程序,能夠極大的提高編程速度和代碼質量,即便不進行重構也同樣如此。github

每當咱們收到一個bug報告時,請先寫一個單元測試來暴露bug。編程

測試是一種風險驅動的行爲,測試的目的是但願找出如今或將來纔可能出現的錯誤。 測試的要訣是:測試你最擔憂出錯的部分。這樣你就能從測試工做中獲得最大的利益。緩存

「花費合理的時間找出大多數的bug」好過「窮盡一輩子抓出全部bug」。安全

從新組織函數

  • 重複代碼 重複代碼應該考慮將其提煉到一個獨立的函數或類中。框架

  • 過長函數 當咱們看見一個過長的函數或者須要一段註釋才能讓人理解其用途的代碼時,咱們就須要將這段代碼放到一個獨立的函數中。 一個函數多長才算合適?在我看來長度不是問題,關鍵在於函數名稱和函數體之間的語義距離。若是提煉能夠強化代碼清晰度,那就去作,就算函數名稱比提煉出來的代碼還要長也無所謂。函數

  • 內聯函數 有時候會遇到某些函數,其內部代碼和函數名稱一樣清晰易讀,咱們就能夠去掉這個函數直接使用其中代碼。工具

  • 內聯臨時變量 若是發現一個臨時變量只被一個簡單表示式賦值一次,而且妨礙了其餘重構手法,咱們就應該讓他內聯化。 直接將變量聲明成final的,能夠檢查變量是否真的是被賦值了一次。性能

  • 以查詢來取代臨時變量

  • 引入解釋性臨時變量 將複雜表達式的結果放到一個臨時變量,以變量名稱來解釋表達式用途。

  • 分解臨時變量

在對象之間搬移特性

在對象設計過程當中,決定把「責任」放在哪裏是很是總要的。這曾經讓我很是苦惱,可是如今我知道,在這種狀況下,能夠運用重構,改變原有的設計。

  • 搬移函數 「搬移函數」是重構理論的支柱。若是一個類有太多行爲,若是一個類和另外一個類高度耦合,咱們就須要搬移函數。

  • 搬移新的字段 隨着系統的發展,你會發現本身須要新的類,並將現有的工做拖到新的類中。若是發現對於一個字段,在其所駐類以外的另外一個類中都有更多函數使用了它,我就會考慮搬移這個字段。

  • 提煉類 一個類應該是一個清晰的抽象,處理一些明確的責任。

簡化表達式

能夠將一個複雜的條件邏輯分解成若干小塊。這樣可使得分支邏輯和操做細節分離。

  • 分解條件表達式 分解表達式能夠突出條件邏輯,更清晰地代表每一個分支的做用,並突出每一個分支的緣由。 作法:將分支語句提煉出來,構成一個獨立的函數。

  • 合併表達式 有時會發現一串的表達式檢查條件各不相同,但最終行爲卻一致。若是這樣就須要使用「邏輯與」或「邏輯或」合併表達式。

  • 合併重複的條件片斷 當全部分支都會執行相同代碼時,就須要將這段代碼搬移到條件表達式以外了。這樣咱們能更加清晰的知道,那些東西是隨着條件變化而變化的、那些是不變的。

  • 移除控制標記 控制標記可使用break或continue來代替,還可使用return直接返回。

  • 以衛語句來取代嵌套表達式 可讓代碼邏輯看起來更加的清晰。

  • 以多態來取代條件表達式 多態的好處在於:若是你須要根據對象的不一樣類型來採起不一樣的行爲,多態使你沒必要寫明顯的條件表達式。

簡化函數調用

- 改函數名 函數的名稱應該準確的表達它的用途。給函數命名有一個好的辦法:首先考慮應該給函數寫上一句這樣的註釋,而後在想辦法將註釋變成函數名稱。

  • 移除參數 參數表明着函數所需的信息,不一樣的參數值有不一樣的意義。若是不去掉多餘的參數,就會讓每一位調用者多費一份心。

  • 將查詢函數和修改函數分離 任何有返回值的函數,都不因該有看到的反作用。

  • 引入參數對象 爲了縮短參數列,咱們可使用一個對象來包裝全部的參數。這樣能夠下降理解和修改函數代碼的難度。

  • 以異常來取代錯誤碼 若是調用者有責任在調用前檢查必要狀態,就拋出非受控異常。

處理歸納關係

  • 劃分邊界 肯定各個字段、方法應該處於子類仍是超類也是咱們常常須要注意的一個點。

  • 提煉子類、超類和接口

  • 摺疊繼承體系 有時咱們會發現某個子類並無帶來該有的價值時,咱們就須要將子類的超類合併。

  • 塑造模板函數 你有一些子類,其中相應的某些函數以相同順序執行相似的操做,可是各個操做細節上有所不一樣。將這些操做分別放進獨立函數中,並保證他們有相同的簽名,因而原函數也變得相同了,而後將原函數移至超類。

  • 以委託取代繼承 當某個子類只使用接口中的一部分,或者不使用繼承而來的數據時,咱們能夠在子類新建一個字段用以保存超類:調整子類函數,令他改而委託超類;而後去掉二者間的繼承關係。

大型重構

  • 梳理並分解機場體系
  • 將過程化設計轉化爲對象設計
  • 提煉繼承體系

重構要點

  1. 須要有充分測試代碼
  2. 每次只作小的改動,而後編譯測試,而後在作改動
  3. 新加功能就不要去重構,重構就不要新加功能
  4. 重構必定要保證對外接口不要改動或者少改動
  5. 作性能重構時儘可能使用度量工具,不要臆測
  6. 當你發如今加一個新功能的時候很費勁,這個時候就須要考慮重構了
  7. 重構通常發生在項目中期
  8. 性能重構是咱們應該優先關注執行頻率較高的代碼
  9. 重構能夠和系統設計達到一種平衡
  10. 任何狀況下咱們應該優先編寫出能夠調試的軟件,而後再試圖優化它使它更快
  11. 一個優秀的程序員是能編寫出讓別人很快看懂理解的代碼
  12. 重構儘可能不要直接刪掉老的接口,而應該將其標註成廢棄

參考

《重構改善既有代碼設計》

爲監控而生的多級緩存框架 layering-cache這是我開源的一個多級緩存框架的實現,若是有興趣能夠看一下

相關文章
相關標籤/搜索