重構改善既有的程式碼設計(重構原則)

Null發表於2019-01-19

重構:對軟體內部結構的一種調整,目的是再不改變軟體的可觀察行為的前提下,提高其可理解性,降低其修改成本。


兩頂帽子

新增新功能 新增新功能時不應該修改既有程式碼,只管新增新功能,通過測試
重構 重構時你就不能再新增功能,只管改程式序結構,此時你不應該新增任何測試,只在絕對必要(用以處理介面變化)時才修改測試

為何重構

  • 重構改進軟體設計
  • 重構使軟體更容易理解1
  • 重構幫助找到bug
  • 重構提高程式設計速度2

何時重構

  • 三次法則

    • 第一次做某件事時只管去做;第二次做類似的事會產生反感第三次再做類似的事,你就應該重構。(事不過三,三則重構)
  • 新增功能時重構
  • 修補錯誤時重構

重構的難題

  • 資料庫重構
  • 修改介面

    • 讓舊介面呼叫新介面,當你要修改某個函式的名稱時請留下舊函式,讓它呼叫新函式。千萬不要複製函式實現,那會讓你陷入重複程式碼的泥淖中難以自拔。你還應該使用java中depreciation註解,將舊介面標記為@deprecated
  • 難以通過重構手法完成設計的改動

    • 先想像重構的情況。考慮選設計方案時,我會問自己:將某個設計重構為另一個設計的難度又多大?看上去很簡單,我就不必太擔心選擇是否得當,於是我就會選擇最簡單的設計,哪怕他不能覆蓋所有潛在的需求也沒關係,但如果預先看不到簡單的重構辦法,我就會在設計上投入更多的力氣。
  • 何時不該重構
    現有程式碼根本不能正常運作。重構之前,程式碼必須起碼能夠在大部分情況下正常運作 如果專案已近最後的期限,你也應該避免重構,如果專案已經非常接近最後期限,你不應該再分心於重構,因為已經沒有時間了。重構能夠提高生產力如果最後你沒有足夠時間,通常就表示你其實早該進行重構。

重構與設計

  • 如果選擇重構,問題的重點就改變了,你仍然做預先設計,但是不必一定找出正確的解決方案,此刻的你只需要得到一個足夠合理的解決方案就夠了。
  • 有了重構,你就可以通過一條不同的途徑來應付變化帶來的風險。你仍舊需要思考潛在的變化,仍舊需要考慮靈活的解決方案。但是你不必再主意實現這些解決方案而是應該問問自己:”把一個簡單的解決方案重構成這個靈活的方案又多大難度?”如果答案是“相當容易”,那麼就只需要實現目前的簡單方案就行了。

間接層和重構(間接層的價值)

  • 允許邏輯共享

    • 比如說一個子函式再兩個不同的地點被呼叫,或超類中的某個函式被所有子類共享
  • 分開解釋意圖和實現

    • 你可以選擇每個類和函式的名字,這給你一個解釋自己意圖的機會。類或函式內部則解釋實現了這個意圖的做法。如果類和函式內部又以更小單元的意圖來編寫,你所寫的程式碼就可以描述其結構中的大部分重要資訊
  • 隔離變化

    • 很可能我在兩個不同的地點使用同一物件,其中一個地點我想改變物件行為,但如果修改了它,我就要冒同時影響兩處的風險。為此我做出一個子類,並在需要修改出引用這個子類。現在,我可以修改這個子類而不必承擔午一中影響另一處的風險。
  • 封裝條件邏輯

    • 物件有一種奇妙的訊息機制:多型訊息,可以靈活而清晰地表達條件邏輯。將條件邏輯轉化為訊息形式,往往能降低程式碼的重複,增加清晰度並提高彈性。

  1. 什麼是難以理解的程式:難以閱讀的程式,難以修改;邏輯重複的程式,難以修改;新增新行為時需要修改已有的程式碼的程式難以修改帶;複雜條件邏輯的程式,難以修改。
  2. 我們希望程式:容易閱讀;所有邏輯都旨在唯一地點指定;新的改動不會危機現有行為;儘可能簡單表達條件邏輯。

相關文章