หนี้ทางเทคนิค (Technical Debt)
เรื่อง นี้เป็นหนึ่งในเนื้อหาของหนังสือ agile samurai ในส่วนของการทำ refactor ตอนนั้นแปลบทนี้ ก็เห็นว่าตัวอย่างที่หนังสือให้มานั้นก็ดีอยู่แล้ว แต่เมื่อไม่กี่วันที่ผ่านมาผมได้เจอกับตัวอย่างเรื่อง technical debt ที่ดีมากๆด้วยตัวเอง เล่นเอาปวดตับ
ปุจฉา: ระบบช้ามาก Query Data ขึ้นมั่ง ค้างส์มั่งและพบว่ามีตารางขนาด 978 สดมภ์อยู่ทำไงดี
วิสัจฉนา: โอวติดเรื่อง performance หรอครับสงสัยว่าจะมีการด้นโค้ดเกิดขึ้นระหว่างงานเร่ง
ปุจฉา: มีวิธีแก้ไขให้มันดีกว่านี้ไหม
วิสัจฉนา: ไม่รู้ค่ะ ก็ลูกค้าต้องการเก็บข้ามูลเยอะเราก็ทำตามนั้น ตอนนั้นไม่มีเวลาคิดทำอะไรได้ ก็ทำไป
ปุจฉา: ??????
จาก บทสนทนานี้เราจะเห็นว่าระบบไม่มี bug เราไม่ได้พูดว่าสิ่งนี้เป็น bug ระบบยังทำงานได้ตามมันควรจะทำเพียงแต่มันทำงานได้ช้าเท่านั้นเองบางครั้งก็ค้างส์ คำถามคือ 978 สดมภ์มาจากไหน ผมเดาได้ง่ายๆคือตอนนั้นงานมันเร่งคนไม่พอต้องส่งงานสิ่งเดียวที่ทำได้คือ “ทำแม่มให้เสร็จไปก่อน” นี่ คือพฤติกรรมคลาสสิคของโปรแกรมเมอร์ ==” สิ่งที่ได้จากการทำงานแบบนี้คือเราสามารถส่ง งานได้จริงแต่เมื่อเราแกะกล่องออกมาเราจะพบว่ามันเต็มไปด้วยโค้ดที่เกิด จากการ improvise มันคือการเขียนโดยไม่ได้คิดเยอะมันคือการ “ทำให้เสร็จ ไม่ใช่ทำให้ถูก” ผลผลิตของการทำงานแบบนี้เราเรียกว่า “Technical Debt” ผมอยากจะแปลเป็นไทยว่า “บาปทางเทคนิค” แต่เท่าที่เรารู้บาปมันแก้ไม่ได้แต่สิ่งที่เราเขียนไปมันแก้ได้ผมเลยเรียก มันว่า “หนี้ทางเทคนิค” แทนหนี้ทางเทคนิคก็คือ code กากๆที่เราสบถมันออกมาจากหัวสมองแบบไม่ได้คิด ว่ามันดีหนือไม่ดีรู้แต่ว่ามันทำงานได้ก็พอเมื่อเรานำ หนี้ของหลายๆคนมารวมกันเราจะได้โคตรพ่อหนี้ทางเทคนิค 978 สดมภ์คือหนึ่งในตัวอย่างนั้น
ผม เชื่อว่าทุกคนที่เคยทำงานเป็นโปรแกรมเมอร์คงเคยสร้างหนี้ทางเทคนิคกันมา ทั้งนั้น ไม่ว่าจะอยู่ในรูปแบบไหนและทุกครั้งที่เราสร้างเรามักจะคิดในใจว่าเดี๋ยวจะ กลับมาแก้ถ้างานเสร็จ แต่!!! ผมเชื่อว่าน้อยคนนักที่จะย้อนกลับไปแก้สิ่งที่ตัวเองเคยทำผิดไว้อันเนื่องมา ด้วยหลายเหตุผล และหนึ่งในเหตุผลที่ก็คือ “แก้ทำไมในเมื่อมันทำงานได้ ใครจะไปกล้าแตะโค้ดที่ Production จะทำไปทำไมถ้าทำต้อง regression test อีกรอบนะ ขี้เป็นเลือด แพงด้วย ถ้ามันช้าก็ซื้อ hardware มาเติม”
นี่คือสิ่งที่เราพบเสมอ มันเป็นความจริง ที่ต้องยอมรับว่าส่วนมากแล้วโปรแกรมเมอร์มักจะไม่กลับไป แก้สิ่งที่ตัวเองทำผิดๆเอาไว้ถ้าไม่จำเป็นเพราะเขาเหล่านั้นไม่มันใจว่าถ้า แก้ไปแล้วระบบจะ ยังสามารถทำงานได้เหมือนเดิมหรือไม่ระบบมันมี dependency เต็มไปหมดเช่นถ้าเราต้องแยกไอ้ 978 สดมภ์ออกจากกันเราจะแน่ใจได้ไงว่ามันจะไม่ไปพังส่วนอื่น
ดังนั้น มันมีวิธีป้องกันไหม ผมไม่พูดถึงทางแก้นะครับ ถ้าเราไปถามโปรแกรมเมอร์หลายๆคนก็คงจะตอบว่า ทำไมไม่เก็บ requirement ดีๆทำให้มันนิ่งๆ ใช้เวลากับการเก็บ requirement ให้มากพอ คำถามคือ “แค่ไหนเรียกว่าพอ?” จากการทำงานมาหลายปีดีดักของผมพบว่าเราต้องทำใจยอมความจริงไปซะ อย่าหลอกตัวเอง requirement นิ่งๆไม่มีในโลก สิ่งเดียวที่เราทำได้คือทำให้โค้ดของเรายืดหยุ่น มากเพียงพอที่จะรับมือกับความเปลี่ยนแปลงนั้นได้ และหนึ่งในการทำให้โค้ดยืดหยึ่นได้มาก ณ ทศวรรษนี้คือการทำ Test Driven Development เราคงจะไม่มานั่งอธิบายกันหรอกว่าไอ้ TDD เนี่ยมันคืออะไร ณ ตรงนี้เพราะมันผิดที่แต่เราเป็นว่าเมื่อเราทำ TDD เราจะได้อะไร
การ ทำ TDD จะทำให้เราได้สิ่งที่เรียกว่า Executable Specification มันคือโค้ดหนึ่งชุดใหญ่ๆที่ถูกเขียนขึ้นมาเพื่อ ตรวจสอบโค้ดที่เราต้องการสร้างขึ้นและตราบใดก็ตามที่เราสามารถทำให้การทดสอบ ข้างใน Executable Specification ผ่านทั้งหมดเราก็มั่นใจได้ว่าโค้ดเราทำงานได้ถุกต้อง
แลัว TDD ช่วยแก้ไขเรื่อง หนี้ทางเทคนิคอย่างไรคำตอบคือ ลองจินตนาการว่าเรามี Executable Specification อยู่แต่งานเร่งมาก สิ่งเดียวที่เราทำได้คือเราเขียนโค้ดที่ทำงานได้และอย่างน้อยต้องไม่ break test นี่แปลว่าอะไร มันแปลว่าเรายังคงสามารถด้นโค้ดได้อยู่แต่สิ่งที่ต่างจากการด้นแบบแรกคือการ ด้นแบบแรกเราด้นไปแบบไม่มี กรอบสิ่งที่เราทำคือการเขียนไปแล้วคาดหวังว่ามัน “น่าจะทำได้” ส่วนการด้นแบบที่สองเรามี Executable Spec คุมชัดเจนว่า “จะด้นก็ด้นไปแต่อย่างน้อยต้อง test ผ่าน” มันเหมือนเรามีกรอบการทำงานที่ชัดเจน
เราลองย้อนกลับไปที่บทสนทนาข้างต้นใหม่แต่เปลี่ยนใหม่เป็นว่าโปรแกรมเมอร์ทำงานแบบ TDD
ปุจฉา: ระบบช้ามาก Query Data ขึ้นมั่ง ค้างส์มั่งและพบว่ามีตารางขนาด 978 สดมภ์อยู่ทำไงดี
วิสัจฉนา: โอวติดเรื่อง performance หรอครับสงสัยว่าจะมีการด้นโค้ดเกิดขึ้นระหว่างงานเร่ง
ปุจฉา: มีวิธีแก้ไขให้มันดีกว่านี้ไหม
วิสัจฉ นา: ไม่ต้องกลัวครับเดี๋ยวเราลอง refactor กันก่อนครับ น่าจะปรับได้หลายกระบวนท่า ไม่ต้องห่วงเรามี Executable Specification ที่สามารถตรวจสอบและกันผลกระทบที่มีต่อการทำงานโดยรวมได้ครับ
ปุจฉา: OTL
คำ ถามปิดท้าย เราต่างเคยสร้าง หนี้ทางเทคนิค แล้วเราเคยคิดที่จะหาทางแก้มันกันบ้างไหม? ถ้าพบว่ามีทางแก้ที่เป็นไปได้จริงอยู่จะลองกันไหม หรือจะทำให้ requirement มันนิ่ง


