การวัดระดับความซับซ้อนของ software นั้น
ใช้สำหรับการวางแผนในการพัฒนา และ ทดสอบระบบงาน
รวมทั้ง ใช้สำหรับการตัดสินใจทำการ refactoring code
เพื่อปรับปรุงเรื่องคุณภาพ และ ป้องกันปัญหาต่างๆ ที่จะเกิดขึ้น
แต่เรามักจะพบว่า ระบบส่วนใหญ่ไม่สนใจเรื่องความซับซ้อนสักเท่าไร
ส่งผลให้การพัฒนาและดูแลระบบเกิดปัญหาต่างๆ ตามมา
สุดท้าย สิ่งที่เราเลือกทำก็คืออะไร
ระหว่าง เขียนมันขึ้นมาใหม่ (Rewrite) หรือ ปรับปรุงให้ดีขึ้น (Refactoring) ?
ความซับซ้อน (Complexity)
คือ ตัวชี้วัดของการทำงานของส่วนต่างๆ ในระบบ
โดยที่ ความซับซ้อนของระบบ เป็นตัวชี้วัดโดยตรงกับเรื่อง
- คุณภาพของระบบ
- ค่าใช้จ่าย
ดังนั้น ถ้าความซับซ้อนของ code ในระบบนั้นสูง นั้น
คุณภาพของ code น่าจะต่ำใช่ไหมนะ ?
แล้วค่าใช้จ่ายในการดูแลและจัดการก็น่าจะสูงไหมนะ ?
โดยสิ่งที่องค์กรหรือทีมต่างๆ มักจะพบเจอปัญหาจาก code ที่มันซับซ้อนดังนี้
- ความเสี่ยงในการเกิด defect ที่น่ากลัวสูง
- ยากต่อการเพิ่ม feature ใหม่ๆ เข้าไป
- ยากต่อการดูแลรักษา
- ยากต่อการทำความเข้าใจ
- ยากในการตรวจสอบความถูกต้อง
ความซับซ้อนของ code มันวัดกันอย่างไรล่ะ
สามารถวัดความซับซ้อนด้วยค่า Cyclomatic Complexity
ทำการวัดความซับซ้อนจาก code ที่เกี่ยวข้องกันเชิงเส้นตรง
นั่นคือแต่ละ class แต่ละ method มันเรียกใช้งานกันอย่างไร
ในแต่ละ method มันขั้นตอนการทำงานเป็นอย่างไร
ซึ่งมันจะสะท้อนว่า การทดสอบจะยาก หรือ ง่าย
รวมไปถึงความน่าเชื่อถือของระบบอีกด้วย
และใช้ค่าความซับซ้อนสามารถนำไปช่วย
estimateเวลาและค่าใช้จ่ายในการพัฒนาและดูแลรักษาด้วย
ค่าความซับซ้อนนั้นช่วยทำให้เรารู้ว่า
- ส่วนไหนที่เราต้องให้ความสำคัญมากๆ
- ต้องหาวิธีการในการทดสอบที่มีประสิทธิภาพ
- รู้ว่าเมื่อไรควรจะหยุดทดสอบ
- จะทำให้ code หรือ ระบบงาน มันทดสอบได้ง่ายขึ้นได้อย่างไร
- เมื่อไรที่ควรจะหยุดดูตัวเอง เหมือนเป็นการส่องกระจก คุณต้องทำมันทุกๆ เช้า ใช่ไหม ?
ดังนั้น ก่อนทำการพัฒนาหรือเพิ่ม feature อะไรเข้าไป
เราสามารถนำค่าความซับซ้อนของ code มาช่วยทำนาย และ ตัดสินใจ ได้
รวมไปถึงทำให้เราเห็นว่า อะไรคือส่วนสำคัญที่ต้องเน้น
ในการพัฒนา และ ทดสอบ เพื่อทำให้ได้คุณภาพตามที่ต้องการ หรือ คาดหวัง
ลองถามทีม หรือ ตัวเองดูว่า
code ที่คุณทำงานอยู๋ด้วยนั้น มันสามารถเพิ่ม feature ใหม่ๆ เข้าไปได้ง่ายหรือไม่ ?
จะไม่ หรือ ไม่แน่ใจ แสดงว่า น่าจะเริ่มมีปัญหาอะไรบางอย่างแล้ว
คุณจะทำงานบน code หรือ ระบบ ด้วยการเดาแบบคนตาบอด
หรือจะนำค่าสถิติต่างๆ เช่น ค่าความซับซ้อนมาใช้ในการตัดสินใจ ดังต่อไปนี้
ตัวอย่างการดูประวัติความซับซ้อนของ method ใน class
คุณเห็นอะไรจากกราฟข้างบนบ้าง ?
เห็นไหมว่า class ไหนที่มีความซับซ้อนสูง
เห็นไหมว่า class ไหนถูกแก้ไขเรื่องความซับซ้อนไปแล้วบ้าง
เห็นไหมว่า code โดยรวมมีค่าความซับซ้อนอย่างไรบ้าง
มันก็น่าจะพอช่วยทำให้เรารับรู้ว่า ระบบเป็นอย่างไร
ไม่ใช่เป็นตาบอดคลำทางแบบเดิมนะ
ตัวอย่างกราฟแสดงความซับซ้อนภาพรวมของค่าความซับซ้อน ที่เกิดขึ้นในทุกๆ การ commit code
คุณเห็นอะไรบ้างจากภาพข้างบน ?
เห็นไหมว่า ระบบที่คุณสร้างนั้นมีความซับซ้อนเพิ่มมาอย่างไร
เห็นไหมว่า code ที่สร้างมามันดี หรือ ควรแก้ไขหรือไม่
ตัวอย่างของการสร้างความสัมพันธ์ของ class/module ต่างๆ ของ code ในระบบ
คุณเห็นอะไรบ้างจากภาพข้างบน ?
เห็นไหมว่า class ไหน มันสัมพันธ์กับส่วนไหนบ้าง
เห็นไหมว่า class ไหน มันมีความสัมพันธ์กับส่วนอื่นน้อยๆ หรือ ทำงานด้วยตัวเอง ซึ่งมันดีมากเลยใช่ไหม สามารถแยกออกไปทำงานได้ง่ายใช่ไหม
เห็นไหมว่า class ไหนมันน่าจะเกิดปัญหา หรือ เป็นปัญหาคอขวดได้
กราฟเรื่องความสัมพันธ์ของ code น่าจะช่วยเราไหมนะ
เพื่อที่จะทำให้เราเห็นว่า code ส่วนไหนมันน่าจะมีปัญหา หรือ มีความซับซ้อนสูงเกินไป
จะได้ทำการแก้ไข หรือ ไม่แก้ไขต่อไป
แล้วถ้าคุณรู้ค่าความซับซ้อนของระบบที่คุณสร้างแล้ว คุณจะทำอย่างไรล่ะ ?
- ไม่สนใจ ช่างมันสิ
- เลือกที่จะแก้ไขไปทีละอย่าง นั่นคือการตั้งเป้าหมายในการแก้ไขปัญหาไปทีละส่วนๆ
การแก้ไขมี 2 ทางเลือก คือ Refactoring และ Rewrite
โดยผมแนะนำให้ทำการ Refactoring นะครับ
ดังนั้น เมื่อพบปัญหา ให้ทำการแก้ไขปัญหาทันที (Continous Improvement)
อย่าปล่อยให้ปัญหามันใหญ่ก่อนจึงทำการแก้ไข
เพราะว่า มันจะใช้เวลาที่สูงมากๆ นั่นหมายถึงค่าใช้จ่ายที่สูงขึ้น
ปิดท้ายด้วยเรื่องหนึ่งที่น่าสนใจ จาก Conway’s Law คือ
Any organization that designs a system will inevitably produce a design
whose structure is a copy of the organization’s communication structure.
คือ โครงสร้างขององค์เป็นอย่างไร ระบบงานที่คุณสร้างก็เป็นเช่นนั้นล่ะนะ
แสดงด้วยรูปภาพแบบขำๆ ดังรูป
อยากเป็นแบบไหนก็เลือกเลยครับ …
Reference Website
http://www.infoq.com/news/2014/10/complexity-software-quality
http://www.methodsandtools.com/archive/archive.php?id=98