移動函式 (Move Function)

★★★★Draft

FromRefactoring

📚 From the Books

移動函式 (Move Function)Refactoring Moves

要讓軟體具備模組特質,相關的元素得待在一起。這件事會動態發生:越了解要做的事,就越知道該如何妥善聚集元素。持續地聚集,正顯示我們的理解在持續提升。

🧠 Why It's a Problem

一個函式若一直在存取「別人家」的資料,它其實住錯了地方。當它參考其他環境元素的量大於當前環境時,就該搬過去——這通常能改善封裝。

TIP

Fowler 提醒:這個決定不容易,而越難決定的搬動,往往越不重要——若兩邊看起來都合理,那多半怎麼放差別都不大,別為此糾結太久。

⚖️ Refactoring

機械步驟:① 檢查函式在原環境用到的所有元素,判斷是否也該一起搬 → ② 把函式複製到目標環境、調整成貼合新家(存取改為 this) → ③ 讓原處委託給新函式或直接更新呼叫端 → ④ 測試 → ⑤ 移除原函式。

前 — send_email 住在 Employee 外面
class Employee {
  constructor(name, email) {
    this.name = name;
    this.email = email;
  }

  printEmployeeDetails() {
    console.log(`Name: ${this.name}, Email: ${this.email}`);
  }
}

function sendEmail(employee, message) {
  console.log(`Sending email to ${employee.email} with message: '${message}'`);
}

const employee = new Employee('John Doe', 'john@example.com');
sendEmail(employee, 'Welcome to the team!');

sendEmail 只靠 employee.email 運作——它參考的全是 Employee 的資料,卻住在外面。

後 — 把它搬進 Employee
class Employee {
  constructor(name, email) {
    this.name = name;
    this.email = email;
  }

  printEmployeeDetails() {
    console.log(`Name: ${this.name}, Email: ${this.email}`);
  }

  sendEmail(message) {
    console.log(`Sending email to ${this.email} with message: '${message}'`);
  }
}

const employee = new Employee('John Doe', 'john@example.com');
employee.sendEmail('Welcome to the team!');

函式搬到資料旁邊,email 參數消失、改用 this.email。行為與它依賴的資料終於同住,封裝更緊。

NOTE

當你發現「該一起搬的其實是一整群資料加方法」,那已經是 Extract Class 的場景了——Move Function 是它的組成步驟之一。

🔑 Takeaways

✍️ My Notes

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

📖 Further Reading