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

Rename Function/Variable

เปลี่ยนชื่อ function หรือตัวแปรให้บอกตรง ๆ ว่าคืออะไรหรือทำอะไร ชื่อใหม่ต้องทำให้ผู้อ่านเข้าใจจุดที่เรียกได้โดยไม่ต้องเปิดดูข้างใน จากนั้นอัปเดต caller ทุกจุดให้ใช้ชื่อใหม่ behavior ไม่เปลี่ยนสักนิด เปลี่ยนแค่ถ้อยคำ

ชื่อที่ชวนเข้าใจผิดแย่กว่าไม่มีชื่อเสียอีก ลองนึกถึง function ชื่อ getCustomer ที่แอบสร้างลูกค้าใหม่ให้ถ้าหาไม่เจอ ตัวแปรชื่อ data ที่เก็บราคาแค่ค่าเดียว หรือ flag ชื่อ check ที่จริง ๆ แล้ว ลบข้อมูลทิ้ง ทุกอันบังคับให้ผู้อ่านต้องเมินชื่อแล้วไปไล่อ่านข้างในแทน ที่เป็นความล้มเหลวที่ชื่อดี ๆ มีไว้ป้องกันพอดี เมื่อไรที่คุณจับได้ว่าตัวเองเปิด implementation อ่านเพียงเพื่อจะรู้ว่าคืออะไร นั่นแหละถึงเวลาเปลี่ยนชื่อ

function ที่ชื่อบอกน้อยกว่างานที่ทำจริงมาก บวกกับตัวแปร local ที่คลุมเครืออีกตัว หลัง refactor ชื่อทั้งสองบอกความหมายออกมาตรง ๆ

// Before
function calc(d: number): number {
const x = d * 0.0085;
return d + x;
}
const result = calc(1200);
// After
function applyDailyInterest(balance: number): number {
const interest = balance * 0.0085;
return balance + interest;
}
const balanceWithInterest = applyDailyInterest(1200);
  1. เลือกชื่อใหม่ แล้วลองอ่านออกเสียงดู ชื่อนั้นบอกผลลัพธ์ ไม่ใช่บอกกลไก ใช่ไหม คนที่เพิ่งเข้ามาอ่านจะเข้าใจจุดที่เรียกโดยไม่ต้องเปิดข้างในหรือเปล่า
  2. ถ้า function เป็นส่วนหนึ่งของ API ที่เผยแพร่แล้ว ให้พิจารณาคงชื่อเดิมไว้เป็น wrapper บาง ๆ ที่ส่งต่อไปยังชื่อใหม่ เพื่อไม่ให้ caller เดิมพัง
  3. เปลี่ยนชื่อที่ declaration จะพึ่ง rename-symbol ของ editor ก็ได้ถ้าเชื่อมือได้ แต่ต้องไล่ดูขอบเขตที่ถูกแก้ทุกครั้ง
  4. อัปเดต caller ทุกจุด — และ comment หรือ string ทุกตัวที่อ้างถึงชื่อเดิม
  5. รัน test การเปลี่ยนชื่อไม่ควรเปลี่ยน behavior ดังนั้นชุด test ที่ผ่านยืนยันว่าคุณแค่ขยับถ้อยคำเท่านั้น
  6. เมื่อ caller ทั้งหมดใช้ชื่อใหม่แล้ว ให้ลบ wrapper ชั่วคราวจากขั้นที่ 2 ทิ้ง

เปลี่ยนชื่อทุกครั้งที่ชื่อทำให้คุณต้องหยุดคิด ทุกครั้งที่ต้องเปิดข้างในอ่านเพื่อจะรู้ว่าคืออะไร หรือทุกครั้งที่ behavior ของ code เคลื่อนห่างจากสิ่งที่ชื่อเคยสัญญาไว้ นี่คือ refactoring ที่เสี่ยงต่ำที่สุดเท่าที่มี และให้ผลตอบแทนสูงที่สุดท่าหนึ่ง เพราะชื่อชัด ๆ ถูกอ่านบ่อยกว่าถูกเขียนหลายเท่า

ต้นทุนคือความวุ่นวายเชิงกลไกที่กระจายไปทั่ว caller และสำหรับ API สาธารณะ อาจเป็นการเปลี่ยนแปลงที่ทำให้ของเดิมพัง บรรเทาได้ด้วยเครื่องมือ rename อัตโนมัติ และในจุดที่สัญญามีความเสี่ยง ให้มีช่วงเวลา deprecation ความเสี่ยงแทบจะคุ้มเสมอ: ผู้อ่านทุกคนที่คุณช่วยให้รอดพ้นจากชื่อที่ชวนสับสน ตอบแทนคุณกลับมา

ใช้ Rename Function/Variable เมื่อหลีกเลี่ยงเมื่อ
ต้องเปิด implementation อ่านถึงจะรู้ว่าทำอะไรชื่อเก่าเป็นส่วนหนึ่งของ public API ที่ publish ไปแล้ว
ชื่อหลอกให้เข้าใจผิดหรือ outdatedมี caller จำนวนมากที่ยังไม่พร้อม migrate
behavior เคลื่อนออกห่างจากสิ่งที่ชื่อสัญญาไว้rename ที่ทำโดยไม่มี test จะไม่รู้ว่าพังหรือเปล่า

⚠️ ไม่ควร Rename Function/Variable เมื่อ:

  • ชื่อเป็นส่วนของ stable public API — ต้องมี deprecation period และ wrapper ชั่วคราว
  • ทำ rename พร้อมกับ behavior change — ให้แยก commit เพื่อให้ git blame ชัดเจน
  • ยังไม่เข้าใจ function นั้นดีพอ — rename ที่ผิดแย่กว่าชื่อเดิม
ทำไมชื่อที่ชวนเข้าใจผิดจึงถือว่าแย่กว่าชื่อที่คลุมเครือ?
เมื่อเปลี่ยนชื่อ function ที่เป็นส่วนหนึ่งของ API ที่เผยแพร่แล้ว อะไรช่วยลดความเสี่ยงที่ caller จะพัง?
หลังการเปลี่ยนชื่อแบบบริสุทธิ์ ชุด test ควรแสดงอะไร?
อะไรทำให้ Rename เป็นหนึ่งในการรีแฟกเตอร์ที่ให้คุณค่าสูงที่สุด?