拆分階段 (Split Phase)

★★★★Draft

FromRefactoring

📚 From the Books

拆分階段 (Split Phase)Refactoring Moves

當一段程式碼同時處理多個關注點,把它拆成獨立的階段。這讓你能單獨處理某個階段而不驚動其他部分——編譯器就是這樣做的:透過不同步驟把高階原始碼一路轉成機器碼。

🧠 Why It's a Problem

一個函式若先做 A、再拿 A 的結果去做 B,其實藏著兩個階段。把它們切開,每個階段各自有清楚的輸入、邏輯與輸出,也清楚顯示哪些資料和函式屬於哪個階段。

TIP

典型訊號是「前半段算出一個中間結果,後半段完全靠這個中間結果繼續」——那道接縫就是階段的邊界。

⚖️ Refactoring

機械步驟:① 找出兩階段之間的接縫(第一階段的產出) → ② 用 Extract Function 把第二階段抽成獨立函式 → ③ 測試 → ④ 把第一階段也抽出,讓它的回傳值成為第二階段的輸入 → ⑤ 測試。

前 — 計算與加稅擠在同一函式
function processOrder(data) {
  const total = data.quantity * data.price;

  let taxRate;
  if (data.type === 'book') {
    taxRate = 0.1;
  } else {
    taxRate = 0.2;
  }

  const tax = total * taxRate;
  return total + tax;
}

const orderData = { type: 'book', quantity: 4, price: 150 };
console.log(`Total cost: ${processOrder(orderData)}`);

「算基本金額」和「依類別加稅」兩件事纏在一起,想單獨改稅制得先看懂整段。

後 — 兩個階段各自獨立
function calculateBaseTotal(quantity, price) {
  return quantity * price;
}

function calculateTotalWithTax(baseTotal, itemType) {
  const taxRate = itemType === 'book' ? 0.1 : 0.2;
  const tax = baseTotal * taxRate;
  return baseTotal + tax;
}

const orderData = { type: 'book', quantity: 4, price: 150 };
const baseTotal = calculateBaseTotal(orderData.quantity, orderData.price);
const totalCost = calculateTotalWithTax(baseTotal, orderData.type);
console.log(`Total cost: ${totalCost}`);

第一階段算出 baseTotal,交給第二階段加稅。稅制要改只動 calculateTotalWithTax,基本金額的計算絲毫不受影響。

🔑 Takeaways

✍️ My Notes

No notes yet — jot your takeaways or Q&A here.

📖 Further Reading