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

Slide Statements

code อ่านง่ายที่สุดเมื่อสิ่งที่เกี่ยวข้องกันอยู่ติดกัน Slide Statements ย้าย statement ขึ้นหรือลงเพื่อให้บรรทัดที่เกี่ยวข้องกันมาเป็นเพื่อนบ้าน ตัวแปรประกาศตรงจุดที่ใช้ครั้งแรก บรรทัด setup อยู่ติดกับการเรียกที่เตรียมไว้ให้ ส่วน behavior ไม่เปลี่ยน เปลี่ยนแค่ลำดับ ท่านี้มักเป็นก้าวแรกเงียบ ๆ ก่อน Extract Function คือเลื่อนชิ้นส่วนที่กระจัดกระจายมารวมเป็นบล็อกเดียวต่อเนื่องกัน แล้วยกทั้งบล็อกออกไปในทีเดียวแบบสะอาด ๆ

ตัวแปรถูกประกาศไว้ที่ด้านบนของ function แต่ไม่ถูกแตะต้องจนกระทั่งสามสิบบรรทัดถัดมา สองบรรทัดที่ทำงานเป็นคู่กันอย่างชัดเจนถูกแยกออกจากกันด้วย code ที่ไม่เกี่ยวข้อง เมื่อคุณพยายาม extract ชิ้นส่วนหนึ่ง คุณพบว่า object ดิบกระจายอยู่ทั่ว function ดังนั้นการ extract จะต้องใช้ parameter ที่เก้กังหรือจะลากเอาบรรทัดที่ไม่ควรอยู่ติดมาด้วย

วิธีรักษาคือเลื่อน statement ที่เกี่ยวข้องกันให้มาอยู่ด้วยกันก่อน เมื่ออยู่ติดกันแล้ว โครงสร้างของ function จะชัดเจน และ refactoring ขั้นต่อไปจะง่ายเป็นเรื่องเล็ก

มีการประกาศสองบรรทัดวางอยู่ด้านบน แต่แต่ละตัวถูกใช้จริงในภายหลังมาก เลื่อนแต่ละบรรทัดลงมาไว้เหนือจุดที่ใช้ครั้งแรก แต่ละค่าจะได้อยู่ติดกับงานที่ต้องใช้

// Before
function summarize(order: Order): string {
const discount = order.basePrice * 0.1;
const tax = order.basePrice * 0.07;
logAccess(order.customerId);
const net = order.basePrice - discount;
recordAudit(order.id);
const gross = net + tax;
return `Net ${net}, Gross ${gross}`;
}
// After
function summarize(order: Order): string {
logAccess(order.customerId);
const discount = order.basePrice * 0.1;
const net = order.basePrice - discount;
recordAudit(order.id);
const tax = order.basePrice * 0.07;
const gross = net + tax;
return `Net ${net}, Gross ${gross}`;
}
  1. เลือก statement ที่คุณต้องการย้ายและช่องปลายทาง
  2. ตรวจ code ที่เลื่อนผ่านว่ามีการรบกวนกันหรือไม่ การเลื่อนจะปลอดภัยก็ต่อเมื่อลำดับไม่สำคัญระหว่างกัน: statement ที่ย้ายและทุก statement ที่ผ่านต้องไม่อ่านค่าที่อีกฝ่ายเขียน และทั้งคู่ต้องไม่มี side effect ที่อีกฝ่ายพึ่งพา
  3. ย้าย statement ไปยังตำแหน่งใหม่
  4. รัน test ถ้ามีอะไรพัง แปลว่าการเลื่อนนั้นข้าม dependency ของจริง ให้ย้ายกลับที่เดิมแล้วคิดใหม่
  5. ทำซ้ำสำหรับ statement ถัดไป โดยเลื่อนทีละอัน เพื่อให้ความล้มเหลวชี้ไปยังการย้ายเพียงครั้งเดียว

เลื่อน statement เพื่อวางการประกาศไว้ติดกับจุดที่ใช้ครั้งแรก เพื่อรวบชิ้นส่วนที่กำลังจะ extract ให้มาอยู่ด้วยกัน หรือเพียงเพื่อให้คู่ setup-กับ-action อ่านต่อกันได้ ท่านี้เสี่ยงต่ำแต่ให้ความชัดเจนสูง และเป็นการอุ่นเครื่องที่เหมาะมากก่อนลงมือ Extract Function

อันตรายจริงเพียงอย่างเดียวคือการพึ่งพาที่ซ่อนอยู่: บรรทัดที่ดูเหมือนเป็นอิสระแต่แอบพึ่งพา side effect ก่อนหน้า (flag แบบ global, state ที่เปลี่ยนแปลงได้ที่ใช้ร่วมกัน, ลำดับผ่าน I/O) test คือผู้คุ้มกัน เมื่อสงสัย ให้เลื่อนทีละก้าวเล็ก ๆ แล้วรัน test หลังการย้ายแต่ละครั้ง

ใช้ Slide Statements เมื่อหลีกเลี่ยงเมื่อ
ต้องการ Extract Function แต่ข้อมูลที่เกี่ยวข้องกระจายอยู่statement มี side effect ที่ขึ้นกับลำดับ
declaration ของ variable ห่างจากที่ใช้มากย้ายข้าม statement ที่แก้ไข data เดียวกัน
code ที่เกี่ยวข้องกันควรอยู่ใกล้กันทีมไม่มี test — การย้ายอาจเปลี่ยน behavior โดยไม่รู้ตัว

⚠️ ไม่ควร Slide Statements เมื่อ:

  • ไม่มี test ครอบคลุม — side effect ที่ซ่อนอยู่อาจเกิดขึ้น
  • statement ที่จะย้ายข้ามมีการ read/write ตัวแปรเดียวกัน
  • กำลังย้ายเพราะ “รู้สึก” ว่าดีกว่า โดยไม่มีเป้าหมาย refactoring ชัดเจน
Slide Statements เปลี่ยนอะไรเกี่ยวกับ code?
ทำไม Slide Statements จึงมักทำก่อน Extract Function?
เมื่อใดที่การเลื่อน statement ผ่านอีกอันหนึ่งจึงปลอดภัย?
อะไรคือเครื่องป้องกันหลักของคุณต่อการเลื่อนที่ไม่ปลอดภัย?