Legacy Code ยิ่งนานยิ่งแย่ลง
Legacy code ไม่ได้ดีขึ้นตามกาลเวลา แต่มันกลับแย่ลง
เมื่อสัปดาห์ที่แล้ว ผมใช้เวลาสามชั่วโมงในการแก้บั๊ก ทั้งที่จริงๆ ควรจะใช้เวลาแค่ 20 นาที ปัญหาก็คือโมดูลตรวจสอบความถูกต้อง (validation module) จากปี 2019 ทุกคนต่างมองข้ามมันเพราะคิดว่า "มันยังใช้งานได้อยู่" แต่จริงๆ แล้วมันไม่ได้ทำงานอย่างที่ควรจะเป็น ผมไปเจอคอมเมนต์ TODO จากปี 2020 อยู่ในไฟล์นั้นด้วย
หลายคนปฏิบัติกับ legacy code เหมือนเป็นหนี้ที่เลือกจะจ่ายเมื่อไหร่ก็ได้ พวกเขาคิดว่าจะค่อยกลับมาจัดการเมื่อมีเวลา แต่จริงๆ แล้ว legacy code เปรียบเสมือนเชื้อรา มันแพร่กระจาย และปนเปื้อนไปยังส่วนอื่นๆ ของระบบ ยิ่งคุณปล่อยไว้นานเท่าไหร่ การทำความสะอาดมันก็จะยิ่งมีราคาแพงขึ้นเท่านั้น
สิ่งนี้ทำให้เกิดวงจรที่เลวร้าย:
- คุณรับช่วงต่อโปรเจกต์ที่ยุ่งเหยิง
- คุณเพิ่ม
if statementเข้าไปอีกหนึ่งตัวเพื่อให้ฟีเจอร์ของคุณทำงานได้ - หกเดือนต่อมา คนอื่นก็ทำแบบเดียวกัน
- หนึ่งปีผ่านไป ไฟล์นั้นมีโค้ดถึง 800 บรรทัดและไม่มีการทดสอบ (tests) เลยแม้แต่นิดเดียว
โค้ดที่ "ยังทำงานได้" เหล่านี้มีต้นทุนแฝง:
- ความเร็วในการพัฒนาลดลง คุณใช้เวลาไปกับการอ่านบริบทมากกว่าการเขียนโค้ด
- บั๊กเพิ่มมากขึ้น การแก้จุดหนึ่งกลับไปทำให้อีกจุดหนึ่งพัง
- การรับพนักงานใหม่ (Onboarding) กลายเป็นเรื่องยาก นักพัฒนาใหม่ต้องดิ้นรนเพื่อทำความเข้าใจว่าทำไมตรรกะ (logic) ถึงถูกเขียนซ้ำไปซ้ำมาอยู่ทุกที่
คอยสังเกตสัญญาณอันตรายเหล่านี้:
- คอมเมนต์ที่ไร้ประโยชน์หรือให้ข้อมูลที่ผิด
- ตรรกะทางธุรกิจ (business logic) ที่ซ้ำซ้อนกันในไฟล์ต่างๆ
- การพึ่งพากันเป็นวงกลม (Circular dependencies) และ high coupling
อย่าพยายามเขียนใหม่ทั้งหมด การเขียนใหม่ทั้งหมด (Full rewrites) มักจะล้มเหลวถึง 80% คุณต้องเสียเวลาหลายเดือนเพื่อสร้างสิ่งที่เคยมีอยู่แล้ว ในขณะที่ธุรกิจกำลังรอฟีเจอร์ใหม่ๆ
ใช้การทำ incremental refactoring ร่วมกับ characterization tests:
- บันทึกพฤติกรรมปัจจุบันด้วยการทดสอบ แม้ว่ามันจะดูแปลกๆ ก็ตาม
- ทำ refactor โดยไม่เปลี่ยนพฤติกรรมนั้น
- ทำซ้ำจนกว่าโค้ดจะอ่านง่าย
- หลังจากนั้นจึงค่อยเปลี่ยนพฤติกรรมด้วยการทดสอบที่แท้จริง
ปฏิบัติตามกฎเหล่านี้เพื่อหลีกเลี่ยง
