Chapter 3 :程式碼的壞味道

  • 2020 年 1 月 22 日
  • 筆記

「如果尿布臭了,就換掉它。」

——Beck奶奶,論保持小孩清潔的哲學


程式碼的壞味道這一章集中論述該何時重構。具體的重構方法在後面的章節。

「沒有任何度量規矩比得上見識廣博者的直覺。你必須培養自己的判斷力,學會判斷一個類中有多少實例變數才算太大,一個函數內有多少程式碼才不算太長。」

​ ——Martin Flower

3.1 改名

深思熟慮給函數,模組,變數和類命名,使其清晰的表明自己的功能和用法。

重構手法之一:改名(改變函數聲明,變數改名,欄位改名)

3.2 消除重複程式碼——提煉函數

同一個類的兩個函數含有相同的表達式——提煉函數。

重複的程式碼段位於同一個超類的不同子類中——函數上移。

3.3 拆分過長函數

「活的最長,最好的程式往往都比較短」

「函數越長,就越難理解」

3.4 過長參數列表

  • 如果發現幾項參數經常出現,可通過引入參數對象將其合併為一個對象。(封裝)
  • 如果發現從現有的數據結構抽出很多數據項作為參數,不如直接傳遞完整的對象
  • 以查詢替代參數:可以像某個參數查詢獲得另一個參數的值。

3.5 全局變數

全局變數的問題:程式碼庫的任何一個角落都可以修改,且無法探測。(程式碼病毒)

處理方法:封裝變數。用函數封裝起來,再搬到類或模組里,控制其訪問許可權。

3.6 發散式變化與霰彈式修改

發散式變化:遇到變化時固定修改某一部分程式碼。

霰彈式修改:程式碼的壞味道其中一種,遇到變化需要修改很多地方。

減小模組的耦合,實現模組的獨立。在添加修改功能時實現程式碼變更的獨立。

3.7 依戀情節

模組化:最大化區域的內部交互,最小化的跨區域交互。

依戀情節:一個函數和另一個模組的函數或者數據交流格外頻繁,遠勝於在自己內部的交流。

3.8 數據泥團

"兩個類中相同的欄位,許多函數簽名中相同的參數…."

在必要時提煉類。引入參數對象,保持對象完整使之參數列表較短。

語義和形式的權衡。

3.9 使用多態替換switch

3.10 循環語句

以管道取代循環。

3.11 冗贅的元素

隨著重構類變得越來越小,適時莊嚴赴義。

3.12 夸夸其談通用性

如果用不到,就不值得。用不上的裝置只會擋路。

3.13 中間人

封裝往往伴隨著委託。

委託應當適度,過度委託就會變成冗餘。

3.14 過大的類

造成重複程式碼。

提煉類,提煉超類。

3.15 注釋

「當你感覺需要寫注釋時,請先嘗試重構。」

注釋的應用場景:

  • 這段程式碼做了什麼
  • 記錄將來的打算
  • 為什麼做