代碼重構 第六章 總結

2022-07-05

第六章 重新組織函數

6.1提煉函數

看見過長的函數或需要注釋才能使人理解的代碼,標志著需要提煉。將函數細粒度的切分為多個獨立函數,函數被復用的機會越大,對函數的覆寫也更容易。另外,切分出的獨立函數取一個對功能描述準確的名字以增強可讀性。不要害怕函數名太長,哪怕函數名比提煉出的代碼還要長也沒關系。

步驟

  • 創(chuàng)建一個新函數,以他的功能命名
    如果不能概括他的功能那就別動他
  • 從源函數復制代碼
  • 檢查提煉出的代碼是否引用了作用域僅限于源代碼的變量
    作為參數傳給提煉的函數
  • 檢查是否有僅限于提煉代碼使用的變量,將其聲明在提煉出的函數中
  • 檢查提煉函數是否改變了某些局部變量
    如果后面用到了被改變的變量,可以將作為它返回值。
    如果需要返回的不是一個值,那盡可能再拆分為多個有單一返回值的函數
  • 編譯測試
    臨時變量太多往往使提煉變得舉步維艱,所以提煉之前盡量先減少臨時變量數量
6.2內聯(lián)函數

以下情況需要用到內聯(lián)函數
1.有些小函數,他的代碼讀起來和函數名一樣清晰易讀,這個時候可以不作為獨立函數
2.有一堆組織不合理的小函數,可以將其組成一個大函數,然后重新拆分為組織合理的小函數

步驟

  • 檢查函數,確定它不具備多態(tài)性
  • 找出調用這個函數的點
  • 將調用的地方換成函數體
  • 編譯測試
  • 刪除函數定義
    如果做的時候不像上面說的這么輕松,遇到了很多難以處理的問題(如遞歸等)。就說明不應該用這種手法重構
6.3內聯(lián)臨時變量

臨時變量往往是用來替換某個查詢值。臨時變量的存在往往會影響重構
唯一需要使用臨時變量的情況是臨時變量被賦予一個函數返回值,這種基本沒有什么危害。

步驟

  • 檢查給臨時變量賦值的語句,確保等號右邊的表達式沒有副作用
  • 如果臨時變量沒有被聲明為final,則聲明為final然后編譯(可以確定臨時變量是否真的只被賦值一次)
  • 找到引用點,替換為賦值時的表達式
  • 每次修改后編譯測試
  • 刪除臨時變量聲明和賦值語句
  • 編譯測試
6.4以查詢取代臨時變量

將臨時變量賦值提煉為一個有返回值的函數
臨時變量的問題在于:他們是暫時的,且只能在所屬函數內使用。導致所在函數變長。把臨時變量替換為查詢,使得同一個類中所有函數都可以使用。在提煉函數之前往往需要這么做。

步驟

  • 找出只賦值一次的臨時變量
  • 聲明為final
  • 編譯
  • 將對臨時變量賦值的語句等號右邊提煉到一個獨立函數中
    可以先聲明為private如果將來還有其他人用,再修改也很容易
    確保提煉出來的函數沒有副作用(修改對象的內容)
  • 編譯測試
  • 將臨時變量改為內聯(lián)臨時變量
6.5引入解釋性變量

將復雜表達式的結構放進一個臨時變量,以變量名解釋用途
這個看起來與消除臨時變量的理念相悖,所以要確定遇到的情形需要用到這個重構手法。
對于提取復雜表達式的重構手法更推薦使用提煉函數,如果算法擁有大量局部變量,直接提取函數很難。這時就需要先用引入解釋性變量清理代碼,搞清楚算法邏輯后再用以查詢取代臨時變量的手法重構。

步驟

  • 聲明一個final變量,將復雜表達式結果賦給它
  • 將用到復雜表達式的地方用臨時變量替換
  • 編譯測試
6.6分解臨時變量

如果一個臨時變量被賦值了多次,表示它承擔了多個責任此時它應該被分解為多個變量。因為同一個變量承擔多個責任會使代碼閱讀者糊涂

步驟

  • 在第一次賦值處修改名稱,聲明為final
  • 用新的變量替換第二次賦值之前對其的引用
  • 在第二次賦值處重新聲明臨時變量
  • 重復
6.7移除對參數的賦值

對于按值傳遞的情況,對參數的任何修改都不會影響原值,在函數中修改參數會使代碼變得難以閱讀,所以需要修改時將參數賦給一個臨時變量,需要返回時,將臨時變量返回即可。

步驟

  • 建立一個臨時變量,把要處理的參數賦給它
  • 將對參數的引用修改為對臨時變量的引用
  • 修改賦值語句為給臨時變量賦值
  • 編譯測試
6.8以函數對象取代函數

對于一些需要拆解但是由于局部變量太多導致難以拆解的可以使用這種方式

步驟

  • 建立一個新類,以拆解出的函數功能為這個類命名
  • 類中新建一個final字段用以存放原函數所在類,用來訪問原函數所在類的字段
  • 新類中建一個構造函數接受源對象,及原函數所有參數,及局部變量
  • 新類中建一個compute函數
  • compute函數中復制原函數代碼,需要使用源對象屬性和局部變量都更改為使用新對象的屬性
  • 修改原函數代碼,改為創(chuàng)建新類的一個對象而后調用compute函數
  • 編譯,測試
    這個步驟過后可以在這個新類里輕松拆解compute函數,所有訪問臨時變量可以改為訪問類屬性
6.9替換算法

對于現(xiàn)有算法,如果有更清晰的解決方式,就應該用更清晰的方式取代復雜的方式
這么做的前提是已經充分理解了原函數

步驟

  • 準備好一個替換算法讓其通過編譯
  • 測試新算法和原函數結果相同
  • 替換原函數
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容