---
# System prepended metadata

title: Chapter 1 重構：第一個範例

---

# Chapter 1 重構：第一個範例

## 重構的第一步：寫測試

> Before you start refactoring, make sure you have a solid suite of tests. These tests must be self-checking.

測試必須是自檢的 (self-checking)，以「**提升開發速度**」、「**花更少時間在 debug 與檢查上**」。進行小幅度的修改，並且在每次修改之後測試

> 務必讓基礎程式比你初次見到它時健康

> 編譯、測試、提交！！！
> 編譯、測試、提交！！！
> 編譯、測試、提交！！！

> 決定程式好壞的關鍵，在於它多麼容易修改

### 一、改良程式結構

用過 *Extract Function* 後，可以看看函式內部能不能做簡單整理
- 變數命名：表達變數目的、包含變數型態（除非想傳達特定的功能資訊，否則都使用[不定冠詞](https://wordvice.ai/tw/blog/definite-indefinite-articles-a-an-the)）
- 移除暫時（區域）變數：可以讓程式碼的提取變得容易
    - *Replace Temp with Query*
    - *Inline Variable*
    - *Change Function Declaration*

:::info
**How to rename all reference in VSCode?**
Put your cursor on the member and click F2 . Then type the new name and hit the Enter key
:::

#### 移除累加變數

:::warning
**重構導致效能下降？**
1. 大部分重構對性能的影響很低
2. 就算真的導致重大影響，還是繼續重構。因為重構好的程式也比較容易調教效能
:::

### 二、新增功能：支援 HTML
*Split Phase*：將計算階段與格式化階段拆開

### 三、新增功能：支援多種收費、集點規則
1. 建立繼承結構：可以容納收費、集點函式
2. *Replace Conditional with Polymorephism*
    - *Replace Type Code with Subclasses*：用子類別來取代型別欄位 (:white_check_mark: Subclass :x: `type`)
    - 但是 JS 的建構式無法直接回傳子類別，所以只好用 function 來取代
        => *Replace Constructor with Factory Function*

---

## Reviews

### Danny
1. 強烈建議一步一步跟著書中的重構步驟，用看的超沒感覺
2. 最原始的範例我放在 [GitHub](https://github.com/dannnyliang/refactoring-notes) 上了，可以拉到 local 後，開個 branch 跟著書來練習
3. [GitHub copilot](https://copilot.github.com/) 跟鬼一樣，function 命名完後自動提示的實作細節，跟書裡一模一樣（但也可能是因為，網路上很多人照著這本書來練習，tranning model 裡面已經很多一樣的資料了）

### Ryan
https://hackmd.io/ifSCIw4SSZukE-h85naMhA

在讀到這段的時候，原本很疑惑將 extract 的 function 放在 `statement` 下的好處。

> This being JavaScript, I can extract `amountFor` into a nested function of `statement`. This is helpful as it means I don't have to pass data that's inside the scope of the containing function to the newly extracted function.

直到實際操作 extract `playFor` 才知道，這樣就不用去處理 `playFor` 中用到的 `plays`。