ข้ามไปยังเนื้อหา

Inline Function

แทนที่การเรียก function เล็ก ๆ ด้วย body ของ function นั้น แล้วลบ function ทิ้ง ใช้ตอนที่ชื่อไม่ได้เพิ่มอะไรจากที่ body บอกชัดอยู่แล้ว

นี่คือวิธีรักษา needless indirection บางที helper เคยมีเหตุผลในอดีต แต่หดเหลือบรรทัดเดียวที่ไม่สำคัญ หรือไม่ชื่อก็แค่พูดซ้ำสิ่งที่ statement เดียวข้างในทำ การไล่ตามชื่อไปยังนิยามที่บอกอะไรไม่มากกว่าจุดที่เรียก คือความเหนื่อยเปล่าของคนอ่าน inline ตัดการกระโดดนั้นทิ้งไป และยังใช้เป็นขั้นตอนล้างบ้านได้ด้วย คือยุบ helper เล็ก ๆ ที่พันกันยุ่งมารวมไว้ที่เดียว แล้วค่อย extract ตามขอบเขตที่ดีกว่าออกมาใหม่

helper ที่แค่ส่งต่อไปยังการตรวจสอบบรรทัดเดียว เพิ่มชั้นขึ้นมาโดยไม่ได้อะไรกลับมา inline ทิ้งไปเลย

// Before
function deliveryFee(driver: Driver): number {
return moreThanFiveTrips(driver) ? 2 : 5;
}
function moreThanFiveTrips(driver: Driver): boolean {
return driver.trips > 5;
}
// After
function deliveryFee(driver: Driver): number {
return driver.trips > 5 ? 2 : 5;
}
  1. เช็กว่า function ไม่เป็น polymorphic เพราะ method ที่ subclass override ไว้ inline ไม่ได้
  2. หาจุดที่เรียกให้ครบ ถ้ามีเยอะให้คิดใหม่ เพราะ inline จะง่ายที่สุดตอนจุดเรียกมีไม่กี่จุด
  3. แทนที่การเรียกแต่ละครั้งด้วยสำเนาของ body แล้วปรับให้เข้ากับ argument จริง
  4. รัน test หลังแทนที่ทุกครั้ง
  5. พอไม่เหลือจุดเรียกแล้ว ก็ลบ function เดิมทิ้ง
  6. รันชุด test ทั้งหมดอีกรอบ เพื่อยืนยันว่าไม่มีใครอ้างถึง function นั้นแล้ว

inline เมื่อ body ชัดเจนอย่างน้อยเท่ากับชื่อ เมื่อกลุ่ม helper ที่จัดโครงสร้างมาไม่ดีควรรวมร่างก่อนแยกใหม่ หรือเมื่อ indirection มาขวางทางคนอ่าน แต่ อย่า inline function ที่ถูกเรียกจากหลายที่ หรือ function ที่ชื่อจับแนวคิดคลุมเครือไว้ได้จริง ๆ เพราะกรณีนั้นชื่อคือเอกสารที่ควรเก็บไว้

ท่าตรงข้ามคือ Extract Function สองท่านี้เป็นคู่หูกัน inline เพื่อยุบโครงสร้างที่ไม่ดี แล้ว extract เพื่อประกอบโครงสร้างที่ดีกว่าขึ้นมาใหม่

ควรใช้ Inline Function ตอนไหน?
Inline Function เป็นท่าตรงข้ามของ refactoring แบบใด?
ทำไมบางครั้งถึงจงใจ inline helper หลายตัวก่อนทำอย่างอื่น?