ถ้าหากคุณลองสังเกตุจะพบว่า Cost ในการค้นหาและแก้ไขข้อผิดพลาด (Bugs, Defects, Issue) ในซอฟต์แวร์จะเพิ่มขึ้นอย่างมากเมื่อเวลาผ่านไปในกระบวนการพัฒนาซอฟต์แวร์ การแก้ไขข้อผิดพลาด ที่ถูกพบหลังจากที่ release ซอฟต์แวร์ไปแล้วนั้น อาจมี cost แพงและมีความเสี่ยงที่สูง

โดยทั่วไปแล้ว cost ที่เกิดขึ้นจากการแก้ไขปรับปรุงนั้นจะสูงกว่าการแก้ไขในระยะก่อนหน้าของแต่ละ phase เป็นอย่างมาก การเปลี่ยนแปลงโค้ดเพื่อแก้ไขข้อผิดพลาด อาจส่งผลต่อฟังก์ชันการทำงานของระบบ ซึ่งอาจจำเป็นต้องทำการแก้ไข เปลี่ยนแปลงส่วนอื่นๆ เพิ่มเติม ทำให้ต้นทุน เวลา และความพยายามเพิ่มขึ้น

Cost ที่กล่าวถึง คือ ต้นทุนของ เงิน เวลา คน และพละกำลังที่ใช้

จริงๆ แล้วเรื่องนี้มีการพิสูจน์และมีรายงานมานานแล้ว ผมขอยกตัวอย่าง research ที่น่าสนใจ กราฟด้านล่างจัดทำโดย สถาบันมาตรฐานและเทคโนโลยีแห่งชาติ (NIST) แสดงให้เห็นว่าความพยายามในการระบุและแก้ไขข้อผิดพลาด จะเพิ่มขึ้นอย่างไร เมื่อซอฟต์แวร์ดำเนินไปตลอดขั้นตอนของการพัฒนาแบบ SDLC

National Institute of Standards and Technology (NIST)

ทีนี้เรามาดูข้อมูลจาก Systems Sciences Institute ของ IBM ที่นำเสนอเรื่อง cost ในการแก้ไขข้อผิดพลาด ที่พบในระหว่างการใช้งานนั้นสูงกว่าค่าใช้จ่ายที่ถูกค้นพบในระหว่างการออกแบบและพัฒนาถึง 6 เท่า ค่าใช้จ่ายในการแก้ไขข้อผิดพลาดที่พบหลัง release จะสูงกว่าค่าใช้จ่ายที่พบในระหว่างการออกแบบถึง 4-5 เท่า และ cost ที่เกิดขึ้นในระหว่างขั้นตอนการ maintenance มากกว่า 100 เท่า

IBM System Science Institute Relative Cost of Fixing Defects

เราจะสังเกตได้ว่า cost ของการค้นหาและแก้ไขข้อผิดพลาด จะเพิ่มขึ้นอย่างมาก เมื่อผ่านไปแต่ละกระบวนการพัฒนาซอฟต์แวร์

ทำไม Cost จึงเพิ่มขึ้นในแต่ละขั้นตอนการพัฒนา

ในขณะที่ developers กำลังเขียนโค๊ดส่วนนั้นอยู่ การหาและแก้ไขข้อผิดพลาดในโค้ดของตัวเองที่กำลังเขียนอยู่นั้น จะทำได้ง่าย เพราะยังจำได้อยู่ว่ามันทำงานยังไง มันจึงง่ายต่อการแก้ไขข้อผิดพลาด หรือ logic ที่ซับซ้อนได้

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

อีกอย่าง คือ การทำงานกับโค๊ดที่ตัวเองไม่เคยทำหรือทำแต่จำไม่ได้แล้ว มันทำให้การ estimate เวลาทำงานจะยิ่งยากเพิ่มตามเข้าไปด้วย

การแก้ไขระบบในขณะที่ developers กำลังทำงานในส่วนนั้นอยู่ มันช่วยให้การแก้ไขนั้นทำได้ง่าย เพราะเขายังจำโค๊ดที่ตัวเองเขียนได้อยู่

ต่อมา ถ้าเข้ามาช่วงขั้นตอนการทดสอบ มันมักจะใช้เวลานานขึ้นในการหาข้อผิดพลาด เพราะต้องหาข้อผิดพลาดบนเครื่อง Local ของ Developers ให้เจอและแก้ไขให้เรียบร้อยก่อนที่จะส่งไปใน phase ถัดไป ซึ่งข้อผิดพลาดส่วนใหญ่จะถูกพบได้ง่ายอยู่แล้ว แต่กับข้อผิดพลาดที่ลึกลับซับซ้อนกว่านั้น เช่น memory leaks หรือ race conditions มันจะยิ่งยากเข้าไปอีก ซึ่งส่วนใหญ่หากตรวจไม่พบตั้งแต่ในขั้นตอนการเขียนโค้ด ก็มักจะหลุดไปเจออีกทีบน production เลย

สุดท้าย ถ้าเราผ่านทุกอย่างไปจนถึงช่วง release ระบบขึ้น production แล้ว มันก็จะยิ่งยากในการหาและจัดการกับข้อผิดพลาดเหล่านั้นขึ้นไปอีก เพราะต้องระมัดระวังไม่ให้ไปกระทบกับผู้ใช้ที่กำลังใช้งานระบบนั้นอยู่ โดยเฉพาะระบบที่มีผู้ใช้งานจำนวนมากและต้องทำงานแบบ 24/7 จะยิ่งยากเข้าไปอีก เพราะระบบเหล่านี้จะต้องพร้อมในการใช้งานและบริการอยู่เสมอ เนื่องจากมันเป็นสิ่งสำคัญสำหรับธุรกิจนั้นเลยก็ว่าได้ ค่าใช้จ่ายในการแก้ไขข้อผิดพลาดในขั้นตอนนี้อาจสูงกว่าการแก้ไขก่อนหน้านี้ในกระบวนการพัฒนาถึง 30 เท่า เนื่องจากมีความท้าทายและความเสี่ยงที่เพิ่มเติมเข้ามา

เราจะจัดการกับสถานะการณ์นี้ได้ยังไง

ค้นหาให้พบมันตั้งแต่เนิ่นๆ และหาข้อผิดพลาดให้บ่อย (Detect Early, Detect Often) โดยปกติแล้ว ในขั้นตอนการพัฒนาเราควรตรวจสอบให้แน่ใจว่าทำยังไงให้สามารถตรวจพบข้อผิดพลาดได้โดยเร็วที่สุด โดยเฉพาะอย่างยิ่งในขณะที่โค้ดกำลังถูกเขียน หรืออยู่ในขั้นตอนการตรวจสอบความถูกต้องของโค้ดอยู่ ก่อนที่จะถูก merge เข้าไปยัง branch หลัก

ซึ่งถ้าหากเราอยากเจอข้อผิดพลาดให้เร็วกว่านั้น ก็ต้องขยับมาทำต้้งแต่ขั้นตอนของการออกแบบ ก่อนลงมือพัฒนาระบบ เช่น System Design, APIs Specification, Test Scenario, Test case เป็นต้น โดยการออกแบบและเตรียมสิ่งเหล่านี้ไว้ก่อน จะทำให้เรามองเห็นข้อผิดพลาดได้ตั้งแต่เนิ่นๆ

"การป้องกันไว้ ดีกว่า แก้"

ส่วนการหาข้อผิดพลาดให้ได้บ่อยๆ คำตอบ คงหนีไม่พ้นการนำเอาพวก automation ต่างๆ เข้ามาใช้ เช่น unit testing, integration testing, APIs testing หรืออาจจะรวมถึง automation test ในระดับ ui เข้ามาช่วยในการหาปัญหาในโค๊ดที่เขียนเข้าไปใหม่ได้ ร่วมถึงการเพิ่มลงไปในกระบวนการ continuous integration ด้วย และเพิ่มความสามารถสามารถในการค้นหาข้อผิดพลาดโดยการใช้เครื่องมือช่วยในการตรวจสอบคุณภาพของโค๊ดที่เขียน เช่น code scan อย่าง sonarqube หรือพวก security scan เป็นต้น

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