🛑 1. The Problem First: "กู้ระเบิดตาเปล่า" (The Black Box Fear)
ลองนึกถึงวันที่คุณได้รับมอบหมายให้แก้ไขฟีเจอร์ในไฟล์ที่ยาว 3,000 บรรทัด ซึ่งไม่มีใครกล้าแตะมา 2 ปีแล้ว:
// ❌ สถานการณ์: โค้ดที่ไม่มีใครเข้าใจลอจิกข้างใน
function doProcess(a, b, c) {
// ... 500 lines of if-else spikes ...
if ((x && !y) || z) {
return handleSpecialCase(a); // 🌋 พัง! ถ้าคุณเปลี่ยนเงื่อนไข 'x'
// ระบบแจ้งเตือนในอีก 10 ไฟล์ที่เหลืออาจจะหยุดทำงานทันทีเพราะมันแอบผูกกันอยู่
}
}
ปัญหา: Legacy Code ไม่ใช่โค้ดที่เก่า แต่มันคือ "โค้ดที่ไม่มีการทดสอบ (Tests)" การเข้าไปแก้ไขโดยไม่วางแผนคือความเสี่ยงมหาศาล คุณอาจจะซ่อมบั๊กหนึ่งจุด แต่สร้างบั๊กใหม่อีกเจ็ดจุดโดยไม่รู้ตัว นี่คือสาเหตุที่ Senior Dev มักจะพูดว่า "อย่าพึ่งแก้ ถ้ายังไม่เข้าใจว่าทำไมมันถึงรันอยู่ได้" ครับ
💡 2. Real-Life Analogy: การซ่อมสายไฟในบ้านเก่า
- Boy Scout Rule: เหมือน "การเก็บกวาดขยะทุกครั้งที่เดินผ่าน". คุณไม่ต้องรีโนเวททั้งบ้านในวันเดียว แค่เห็นจานวางทิ้งไว้ก็ล้าง เห็นขยะก็เก็บ (Refactor เล็กๆ ทุกครั้งที่เข้าไปแก้บั๊ก)
- Sprout Method: เหมือน "การต่อปลั๊กพ่วงออกมาใหม่". แทนที่คุณจะรื้อสายไฟเดิมในผนังที่พันกันยุ่งเหยิง คุณเลือกเดินสายไฟใหม่แยกออกมาเพื่อรองรับเครื่องใช้ไฟฟ้าเครื่องใหม่ (Feature ใหม่) เพื่อลดการกระทบกระเทือนของเดิม
- Strangler Fig Pattern: เหมือน "กาฝากที่ค่อยๆ โตคลุมต้นไม้ใหญ่". คุณสร้างระบบใหม่ขนานไปกับระบบเดิม แล้วค่อยๆ ย้ายหน้าที่จากตัวเก่ามาตัวใหม่ทีละนิด จนต้นไม้ต้นเดิมตายไปและเหลือเพียงกาฝาก (ระบบใหม่) ที่แข็งแรงแทน
🚀 3. Execution Journey: มหากาพย์การกู้ระเบิด (The Safe Workflow)
Senior จะไม่แก้โค้ดก่อนที่จะมี "ตาข่ายนิรภัย" (Safety Net)
🛠 Step-by-step:
- The Lockdown: เขียน Test เพื่อ "ล็อก" พฤติกรรมปัจจุบันไว้ก่อน (Characterization Test) เพื่อให้รู้ว่าโค้ดเดิมทำงานยังไง (แม้จะมีบั๊กก็ต้องเก็บไว้ก่อน!)
- The Small Step: เริ่ม Refactor ทีละบรรทัด (เปลี่ยนชื่อตัวแปร, แยกฟังก์ชันย่อย) และรัน Test วนไปเรื่อยๆ ทุุกครั้งที่แก้
- The Sprout: ถ้าต้องเพิ่มฟีเจอร์ใหม่ ให้เขียนเป็นฟังก์ชัน "บริสุทธิ์" (Pure Function) แยกต่างหากแล้วค่อยเรียกใช้ในโค้ดเก่า
- The Verification: เมื่อแก้เสร็จ ตาข่ายนิรภัย (Test) ต้องยังเป็นสีเขียวเหมือนเดิม 100%
// ✅ Best Practice: ใช้ Sprout Method เพื่อความปลอดภัย
// 🛠 [Legacy Function]
function processOrder(order) {
// ... logic เก่า 200 บรรทัดที่น่ากลัว ...
// 🛠 สร้างฟังก์ชันใหม่แยกออกมา (Sprout) เพื่อคำนวณภาษีใหม่
const tax = calculateNewVat(order.amount);
order.total += tax;
// ... logic เก่าต่อ ...
}
🪤 4. The Junior Trap: โรค "Big Bang Rewrite"
จูเนียร์มักจะทนเห็นโค้ดเน่าไม่ได้และเสนอว่า "ขอเวลา 1 เดือน รื้อเขียนใหม่หมดเลยดีกว่าพี่":
// ❌ Junior Trap: ทุบทิ้งทำใหม่
// 🌋 พัง! การเขียนใหม่ทั้งหมดมักจะใช้เวลานานกว่าที่คิด 3 เท่า
// และคุณจะเผลอทำ "ฟีเจอร์ลับ" ที่โค้ดเก่าทำได้หายไป จนเกิด Regression บานปลาย
ระวัง: การเขียนใหม่ (Rewrite) คือความล้มเหลวของการจัดการวิศวกรรมในหลายๆ ครั้ง ✅ การแก้ไข: จงทำ Incremental Refactoring ค่อยๆ แก้ทีละส่วนในขณะที่ระบบยังสร้างรายได้ให้บริษัทได้อยู่เสมอครับ
⚖️ 5. The Why Matrix: แก้คนเดียว vs แก้ทั้งระบบ
| หัวข้อ | แก้เฉพาะหน้า (Quick Fix) | Refactoring (Senior Style) |
|---|---|---|
| ความเร็ว | ⚡⚡⚡ เร็วมากในตอนนี้ | ช้ากว่าในช่วงแรก |
| หนี้ทางเทคนิค | 🌋 เพิ่มขึ้น (Technical Debt) | ⚡⚡ ลดลงอย่างมาก |
| ความเสี่ยง | สูง (ไม่รู้จะพังตรงไหน) | 🚀 ต่ำ (มี Test คุม) |
| ความภูมิใจ | ต่ำ (โค้ดเน่ากว่าเดิม) | 🚀 สูง (โค้ดสะอาดขึ้นทุกวัน) |
🎓 6. Senior Mindset Summary
การเป็น Senior คือการมองว่า "ความรับผิดชอบของเราไม่ใช่แค่เขียนโค้ดใหม่ แต่คือการดูแลรักษาโค้ดเก่าให้คงคุณค่าอยู่ได้". การ Refactor ไม่ใช่กิจกรรมพิเศษที่ต้องขออนุญาตทำ แต่มันคือส่วนหนึ่งของการเขียนโปรแกรมที่ดีอย่างแยกไม่ออกครับ!