重構的時機和方法 Five Lines of Code: How and When to Refactor

[法] 克裡斯蒂安·克勞森(Christian Clausen)著 郭濤 譯

  • 重構的時機和方法-preview-1
  • 重構的時機和方法-preview-2
重構的時機和方法-preview-1

買這商品的人也買了...

商品描述

每個代碼庫都包含一些錯誤和低效之處,你需要將其找出並完成修正。以正確的方式進行重構,代碼就會變得優雅、易讀和易維護。

在本書中,你將學習一種獨特的重構方式,可以在5行或更少的代碼中實現任何方法。這本書揭示了一個資深開發人員都知道的秘密:有時候敲定代碼並在稍後進行修復會更快。

對於所有技術水平的開發人員來說,本書以全新視角審視重構。你將掌握作者的創新方法,學習一些具體的規則,將任何方法簡化為5行或更少。書中還介紹了重構的時機、適用於大多數常見問題的特定重構模式,以及應該完全刪除的代碼特徵。

本書的主要內容包括:

  • 壞代碼的標志
  • 在甚至不理解代碼的情況下安全地改進它
  • 平衡優化和代碼通用性
  • 正確的編譯器實踐

這本書對於想要改進代碼質量並學習有效重構技巧的開發人員非常有價值。它提供了實用的指導和方法,幫助你在短時間內改進代碼,提高效率並減少錯誤。無論你是初學者還是經驗豐富的開發人員,都能從中獲益

目錄大綱

目    錄

 

第Ⅰ部分

通過重構電腦游戲來學習

第1章 重構 3

1.1  什麽是重構 4

1.2  技能:重構什麽 5

1.2.1  代碼異味示例 5

1.2.2  規則示例 6

1.3  文化:什麽時候重構 6

1.3.1  在遺留系統中重構 7

1.3.2  什麽時候不應該重構 8

1.4  工具:如何(安全地)重構 8

1.5  入門所需的工具 9

1.5.1  編程語言:TypeScript 9

1.5.2  編輯器:Visual Studio Code 9

1.5.3  版本控制:Git 10

1.6  總體示例:一款2D益智游戲 10

1.7  關於實際軟件的說明 12

1.8  本章小結 12

第2章 重構的內部原理 13

2.1  提高可讀性和可維護性 13

2.1.1  使代碼更好 13

2.1.2  維護代碼而不改變代碼作用 15

2.2  獲得速度、靈活性和穩定性 16

2.2.1  優先選擇組合而非繼承 16

2.2.2  通過添加而非修改來更改代碼 17

2.3  重構與你的日常工作 18

2.4  在軟件上下文中定義“域” 18

2.5  本章小結 19

第3章 拆分長函數 21

3.1  建立第一條規則:為什麽是5行 22

3.2  引入重構模式來分解函數 24

3.3  分解函數以平衡抽象 32

3.3.1  規則:EITHER CALL OR PASS 32

3.3.2  應用規則 33

3.4  好的函數名稱的屬性 33

3.5  分解任務太多的函數 36

3.5.1  規則:IF ONLY AT THE START 36

3.5.2  應用規則 37

3.6  本章小結 39

第4章 讓類型代碼發揮作用 41

4.1  重構一個簡單的if語句 41

4.1.1  規則:NEVER USE IF WITH ELSE 42

4.1.2  應用規則 43

4.1.3  重構模式:REPLACE TYPE CODE WITH CLASSES 45

4.1.4  將代碼推入類 48

4.1.5  重構模式:PUSH CODE 

INTO CLASSES 51

4.1.6  內聯一個多餘的方法 55

4.1.7  重構模式:INLINE METHOD 55

4.2  重構一個大的if語句 57

4.2.1  去除泛化 61

4.2.2  重構模式:SPECIALIZE METHOD 63

4.2.3  唯一允許的switch 65

4.2.4  規則:NEVER USE SWITCH 66

4.2.5  消除if 67

4.3  解決代碼重復問題 69

4.3.1  不能用抽象類代替接口嗎 71

4.3.2  規則:ONLY INHERIT FROM INTERFACES 71

4.3.3  所有這些代碼重復是怎麽回事 72

4.4  重構一對復雜的if語句 73

4.5  刪除無用代碼 76

4.6  本章小結 77

第5章 將類似的代碼融合在一起 79

5.1  統一相似的類 80

5.2  統一簡單條件 93

5.3  統一復雜條件 96

5.3.1  對條件使用算術規則 97

5.3.2  規則:USE PURE CONDITIONS 98

5.3.3  應用條件算術 100

5.4  跨類統一代碼 101

5.4.1  引入UML類圖描繪類關系 106

5.4.2  重構模式:INTRODUCE STRATEGY PATTERN 108

5.4.3  規則:NO INTERFACE WITH ONLY ONE IMPLEMENTATION 114

5.4.4  重構模式:EXTRACT INTERFACE FROM 

IMPLEMENTATION 115

5.5  統一類似函數 118

5.6  統一類似代碼 121

5.7  本章小結 125

 

第6章 保護數據 127

6.1  無getter封裝 127

6.1.1  規則:DO NOT USE GETTERS OR SETTERS 127

6.1.2  應用規則 129

6.1.3  重構模式:ELIMINATE GETTER OR SETTER 131

6.1.4  消除最後的getter 133

6.2  封裝簡單數據 136

6.2.1  規則:NEVER HAVE COMMON AFFIXES 136

6.2.2  應用規則 138

6.2.3  重構模式:ENCAPSULATE DATA 143

6.3  封裝復雜數據 145

6.4  消除序列不變量 152

6.5  以另一種方式消除枚舉 155

6.5.1  通過私有構造函數進行枚舉 155

6.5.2  將數字重新映射到類 157

6.6  本章小結 159

第Ⅱ部分 學以致用

第7章 與編譯器協作 163

7.1  瞭解編譯器 163

7.1.1  缺點:停機問題限制了編譯時知識 164

7.1.2  優點:可達性確保方法返回 164

7.1.3  優點:明確賦值防止訪問未初始化的變量 165

7.1.4  優點:訪問控制有助於封裝數據 166

7.1.5  優點:類型檢查證明屬性 166

7.1.6  缺點:取消引用null會使應用程序崩潰 167

7.1.7  缺點:算術錯誤導致溢出或崩潰 167

7.1.8  缺點:越界錯誤使應用程序崩潰 168

7.1.9  缺點:無限循環使應用程序停滯 168

7.1.10  缺點:死鎖和競爭條件導致意外行為 169

7.2  使用編譯器 170

7.2.1  使編譯器運行 171

7.2.2  不要對抗編譯器 173

7.3  信任編譯器 178

7.3.1  教編譯器不變量 178

7.3.2  註意警告 180

7.4  完全信任編譯器 180

7.5  本章小結 181

第8章 遠離註釋 183

8.1  刪除過時的註釋 184

8.2  刪除註釋掉的代碼 185

8.3  刪除不重要的註釋 186

8.4  將註釋轉換為方法名稱 186

8.5  保留記錄不變量的註釋 187

8.6  本章小結 188

第9章 喜歡刪除代碼 189

9.1  刪除代碼可能是下一個前沿 190

9.2  刪除代碼以消除偶然復雜性 190

9.2.1  缺乏經驗導致的技術無知 191

9.2.2  時間壓力造成的技術浪費 192

9.2.3  環境造成的技術債務 192

9.2.4  增長帶來的技術拖累 192

9.3  根據親密程度對代碼進行分類 193

9.4  刪除遺留系統中的代碼 194

9.4.1  使用絞殺者模式進行瞭解 194

9.4.2  使用絞殺者模式改進代碼 196

9.5  從凍結項目中刪除代碼 196

9.5.1  將期望的結果設為默認 197

9.5.2  通過“探針並穩定”模式最大

限度減少浪費 197

9.6  在版本控制中刪除分支 198

9.7  刪除代碼文檔 199

9.8  刪除測試代碼 200

9.8.1  刪除樂觀測試 200

9.8.2  刪除悲觀測試 200

9.8.3  修復或刪除不穩定測試 201

9.8.4  重構代碼以消除復雜的測試 201

9.8.5  專門化測試以加快速度 201

9.9  刪除配置代碼 202

9.10  刪除代碼以消除庫 203

9.11  從工作功能中刪除代碼 205

9.12  本章小結 206

第10章  永遠不要害怕添加代碼 207

10.1  接受不確定性:進入危險 207

10.2  使用探針實驗剋服對構建錯誤事物的恐懼 208

10.3  以固定比例剋服對浪費或風險的恐懼 209

10.4  通過逐步改進剋服對不完美的恐懼 210

10.5  復制和粘貼效果如何改變速度 211

10.6  通過可擴展性進行添加修改 211

10.7  通過添加修改可實現向後兼容 212

10.8  通過功能切換進行添加修改 213

10.9  通過抽象分支進行添加修改 216

10.10  本章小結 218

第11章  遵循代碼中的結構 221

11.1  根據範圍和來源分類結構 221

11.2  代碼反映行為的3種

方式 222

11.2.1  在控制流中表達行為 223

11.2.2  在數據結構中表達行為 224

11.2.3  在數據中表達行為 227

11.3  添加代碼以暴露結構 229

11.4  觀察而不是預測且使用經驗技術 229

11.5  在不理解代碼的情況下獲得安全性 230

11.5.1  通過測試獲得安全性 230

11.5.2  通過掌握獲得安全性 230

11.5.3  通過工具輔助獲得安全性 230

11.5.4  通過正式驗證獲得安全性 231

11.5.5  通過容錯獲得安全性 231

11.6  識別未利用的結構 231

11.6.1  通過提取和封裝來利用空白 231

11.6.2  通過統一來利用重復 233

11.6.3  通過封裝來利用共同詞綴 235

11.6.4  通過動態調度來利用運行時類型 236

11.7  本章小結 237

第12章  避免優化和通用性 239

12.1  力求簡單 240

12.2  何時以及如何通用 241

12.2.1  最小化構建以避免通用性 242

12.2.2  統一穩定性相似的事物 242

12.2.3  消除不必要的通用性 242

12.3  何時以及如何優化 243

12.3.1  優化前重構 243

12.3.2  根據約束理論進行優化 245

12.3.3  使用指標指導優化 247

12.3.4  選擇好的算法和數據結構 248

12.3.5  使用緩存 249

12.3.6  隔離優化代碼 250

12.4  本章小結 251

第13章  讓壞代碼看起來很糟糕 253

13.1  用壞代碼表明過程問題 253

13.2  分成原始代碼和遺留代碼 254

13.3  定義壞代碼的方法 255

13.3.1  本書中的規則:簡單而具體 255

13.3.2  代碼異味:完整而抽象 256

13.3.3  圈復雜度:算法(客觀) 256

13.3.4  認知復雜度:算法(主觀) 257

13.4  用於安全破壞代碼的規則 257

13.5  安全破壞代碼的方法 258

13.5.1  使用枚舉 258

13.5.2  使用整數和字符串作為類型代碼 259

13.5.3  在代碼中放入魔術數字 259

13.5.4  在代碼中添加註釋 260

13.5.5  在代碼中添加空白 261

13.5.6  根據命名對事物進行分組 261

13.5.7  為名稱添加上下文 262

13.5.8  創建長方法 262

13.5.9  給方法多個形參 263

13.5.10  使用getter和setter 264

13.6  本章小結 265

第14章  收尾工作 267

14.1  回顧本書的旅程 267

14.1.1  第I部分:動機和具體化 267

14.1.2  第Ⅱ部分:拓寬視野 268

14.2  探索基本原則 268

14.2.1  尋找更小的步驟 268

14.2.2  尋找底層結構 269

14.2.3  使用規則進行協作 269

14.2.4  團隊優先於個人 269

14.2.5  簡單性優先於正確性 270

14.2.6  使用對象或高階函數 270

14.3  後續方向 271

14.3.1  微架構路線 271

14.3.2  宏架構路線 272

14.3.3  軟件質量路線 272

14.4  本章小結 272

附錄  為第Ⅰ部分安裝工具 275