ช่วงนั่งรอขึ้นเครื่องบินกลับบ้าน
ได้อ่านเรื่อง Prevent Bugs เป็นบทที่ 5 จากหนังสือ Timeless Laws of Software Development
จึงนำมาสรุปไว้นิดหน่อย
น่าจะพอมีประโยชน์สำหรับนักพัฒนากันบ้าง
เริ่มต้นด้วยคำถามคือ นักพัฒนาชอบการสร้าง feature ใหม่ ๆ หรือทำการแก้ไข bug ? คิดว่าส่วนใหญ่ น่าจะชอบการสร้าง feature ใหม่ ๆ มากกว่านะแต่โชคไม่ดีเท่าไร ที่ bug มันเกิดขึ้นได้ตลอดเวลา ไม่พอนะ นักพัฒนาชอบซ่อน bug ไว้ เมื่อเวลาผ่านไปนาน ๆ จำนวน bug สะสมยิ่งเยอะ การมาแก้ไข bug ในภายหลังเป็นเรื่องที่ไม่สนุกเลย บางทีมมีช่วงเวลาสำหรับการแก้ไข bug เป็นสัปดาห์ด้วยนะ หรือถ้าทำงานเป็นรอบ ก็มักจะมีรอบของการแก้ไข bug ซึ่งคิดว่ามันไม่น่าจะเป็นทางที่ดีนะ !!
สาเหตุที่ทำให้มี bug จำนวนสูง ประกอบไปด้วย
- เน้นความเร็วในการพัฒนามากกว่าความถูกต้อง (Deadline-Driven Development)
- ชอบแก้ไข bug มากกว่าป้องกัน ยิ่งที่ไหนมีทีม tester/QA ยิ่งไม่ต้องสนใจเลย เดี๋ยวมีคนทดสอบให้
- ไม่รู้ และ ไม่เรียนรู้วิธีการป้องกันไม่ให้เกิด bug
- ขาดการวางแผนที่ดี
- ขาดเทคนิคการทดสอบที่ดี
- สถาปัตยกรรมของระบบงาน เอื้อต่อการสร้าง bug อย่างมาก
- ขั้นตอนการพัฒนาที่แย่
- การจัดการ priority ของงานที่ห่วย
- สุดท้ายคือนักพัฒนานั่นเอง
ดังนั้นมาเปลี่ยนแนวคิด แนวปฏิบัติกัน โดยเริ่มต้นด้วยการเรียนรู้วิธีการป้องกัน bug กันดีกว่า (Prevent Bugs)
1. เริ่มที่ตัวนักพัฒนาเองก่อน
ต้องถามตัวเราเองว่า ระหว่างทำให้เสร็จเร็ว ๆ กับทำให้ดี จะเลือกอะไร ? ถ้าบอกว่า เลือกทั้งคู่สิ มันเป็นไปไม่ได้เลย ใช่ไหม ยิ่งเร่งยิ่งพังยิ่ง bug เยอะ ที่สำคัญนักพัฒนาจะทิ้งทุกอย่างเพื่อให้เสร็จเร็ว ๆ มันส่งผลดีไหมละ ? ดีนะคือ งานตรงเวลา เสร็จเร็ว KPI ดี แต่ bug เพียบ rework เพียบ แบบนี้ดีหรือไง ?ดังนั้นถ้าคุณบอกว่า ต้องการงานที่มีคุณภาพแล้ว สิ่งที่ต้องทำเลยคือ การจัดเรียง priority ของงาน ว่าอะไรก่อนหลัง ไม่ใช่มีแต่งานเร่งด่วนมาก กับ งานด่วนสุด ๆนักพัฒนาที่ดีต้องให้เวลากับการวางแผนงานที่จะทำ เขียน code ที่ดี ป้องกันหรือลดจำนวน bug ลงให้มาก มันอาจจะดูว่าทำงานช้ากว่าเดิม ตอบเลยว่าใช่ แต่มันจะส่งผลดีในระยะยาว นั่นคือคุณจะมี productivity สูงขึ้น อย่าลืมว่า งานที่คุณทำอยู่นั้นไม่ใช่งานระยะสั้น แต่มันคืองานระยะยาว หรือเทียบได้กับการวิ่งมาราธอน คุณคงไม่เร่ง speed ตั้งแต่เริ่มใช่ไหม ?
2. นักพัฒนาไม่สนใจ warning ต่าง ๆ จากเครื่องมือที่ใช้งานเลย
ยกตัวอย่างเช่น IDE หรือ build tool มักจะทำการแจ้ง warning หรือคำเตือนต่าง ๆ ของ code ที่เราเขียนขึ้นมา พบว่านักพัฒนาส่วนใหญ่จะไม่สนใจ ปล่อยมันไป เพราะว่าแค่เตือน มันไม่ได้พังหรือ fail นะ แต่รู้ไหมว่า warning เหล่านั้นมันคือ error ที่จะเกิดขึ้นในอนาคตอันใกล้ !! ดังนั้นจงแก้ไขซะแต่ก็มีนักพัฒนาจำนวนไม่น้อย แก้ไขด้วยการ ignore/suppression ไป !! ไม่น่าจะดีเท่าไรนะบางทีมดีขึ้นมาคือ ตั้งค่า warning เป็น error ไปเลย แต่ทำอยู่ได้ไม่นานก็เปลี่ยนกลับ เพราะว่ามันเยอะเหลือเกิน !!
3. จัดการตรวจสอบ inputให้ดี
น่าจะเป็นสิ่งสำคัญมาก ๆ ของทุกระบบงาน เพื่อตรวจสอบว่า input ที่เข้ามาเป็นอย่างไร ตรงตามที่ต้องการหรือไม่ อาจก่อให้เกิดความเสียหายหรือไม่ แต่การตรวจสอบนั้น แนะนำให้ตรวจสอบตรง boudary ของระบบเท่านั้น ยกตัวอย่างเช่น REST API ในส่วนที่รับ request จากผู้ใช้งานนั้น อาจจะเป็นส่วนของ controller ดังนั้นก็ตรวจสอบในส่วนของ controller พอ ถ้า controller ไปเรียกส่วนอื่น ๆ เช่น service, model, repository แล้ว ก็ไม่จำเป็นต้องไปตรวจซ้ำอีกนะ มันเปลืองเวลา และ code ระหว่างการแจ้ง error ของ input กับป้องกัน input error เลือกอะไรดี ? เลือกยากนะ ถ้ามีทั้งส่วนของ Frontend และ Backend ดังนั้นทำทั้งสองส่วนเลย ระบบที่ดี user interface มันต้องใช้งานง่าย เป็นมิตรต่คนใช้งาน แถมต้องทำการตรวจสอบ input ให้อีกด้วย4. ลด condition logic ต่าง ๆ ใน code ของระบบลงไปบ้าง
ทั้งลดการตรวจสอบข้อมูลต่าง ๆ ทั้งการใช้ assertion มาช่วย แถมช่วย debug ให้อีกนะ ทั้งการใช้หลักการ polymorphism มาใช้ เป้าหมายเพื่อลดความซับซ้อนของระบบ ช่วยทำให้การทดสอบเร็วและง่ายขึ้น แถมช่วยทำให้เราเข้าใจระบบง่ายขึ้นอีกด้วย ที่สำคัญช่วยลดข้อผิดพลาดลงไปอีกด้วย5. เน้นเรื่องของ user-define type หรือ abstraction layer ใน code
เน้นเรื่องของ readability เน้นเรื่องการลดข้อผิดพลาดจากความเข้าใจผิด รวมถึงการระมัดระวังการใช้งาน premitive data type ของภาษาโปรแกรมด้วย ในหนังสือยกตัวอย่าง code ชุดนี้ [code] double computeHydrostaticPresure() { } [/code] คำถามคือ method นี้ทำการ return ข้อมูลเป็นหน่วยอะไร ? ซึ่งก่อนให้เกิดความผิดพลาดจากความเข้าใจผิดได้ ขึ้นอยู่กับผู้นำไปใช้งานเลย ที่สำคัญ code ชุดนี้มาจากระบบงาน The NASA Mars Climate Orbiter และคนนำไปใช้งานแบบเข้าใจผิด ก่อให้เกิดความผิดพลาดตามมา ดังนั้นแทนที่จะเป็น double ก็ให้สร้าง user-defined type ขึ้นมาแทนดีกว่านะ อาจจะทำให้ code เยอะขึ้น มีความซับซ้อนมากขึ้น แต่สิ่งที่ได้มา code ที่อ่านเข้าใจได้ง่าย แถมลดความเข้าใจผิด หรือ สิ่งที่จะทำให้ผิดพลาดลงไปได้ มันก็น่าทำนะลองทำไปปฏิบัติกันดูนะครับ น่าจะมีประโยชน์สำหรับนักพัฒนากันบ้าง