ช่วงนั่งรอขึ้นเครื่องบินกลับบ้าน
ได้อ่านเรื่อง 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 หรือเกิดน้อย ๆ นะ ?
การตามแก้ไข bug มันไม่สนุกเลย
แถมไม่ได้เพิ่ม value และ productivity กันเลย

ดังนั้นมาเปลี่ยนแนวคิด แนวปฏิบัติกัน
โดยเริ่มต้นด้วยการเรียนรู้วิธีการป้องกัน 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 ชุดนี้

double computeHydrostaticPresure() { }

คำถามคือ method นี้ทำการ return ข้อมูลเป็นหน่วยอะไร ?
ซึ่งก่อนให้เกิดความผิดพลาดจากความเข้าใจผิดได้
ขึ้นอยู่กับผู้นำไปใช้งานเลย
ที่สำคัญ code ชุดนี้มาจากระบบงาน The NASA Mars Climate Orbiter
และคนนำไปใช้งานแบบเข้าใจผิด
ก่อให้เกิดความผิดพลาดตามมา
ดังนั้นแทนที่จะเป็น double ก็ให้สร้าง user-defined type ขึ้นมาแทนดีกว่านะ

อาจจะทำให้ code เยอะขึ้น
มีความซับซ้อนมากขึ้น
แต่สิ่งที่ได้มา code ที่อ่านเข้าใจได้ง่าย
แถมลดความเข้าใจผิด หรือ สิ่งที่จะทำให้ผิดพลาดลงไปได้
มันก็น่าทำนะ

ลองทำไปปฏิบัติกันดูนะครับ
น่าจะมีประโยชน์สำหรับนักพัฒนากันบ้าง