'ความซับซ้อนตามวัฏจักรของโค้ดของฉันหมายถึงอะไร


42

ฉันใหม่สำหรับการวิเคราะห์โค้ดแบบสแตติก แอปพลิเคชันของฉันมีความซับซ้อนตามวัฏจักร 17,754 แอปพลิเคชันนั้นมีรหัสเพียง 37,672 บรรทัด มันถูกต้องหรือไม่ที่จะบอกว่าความซับซ้อนนั้นสูงตามบรรทัดของโค้ด? อะไรคือความซับซ้อนของวงจรที่บอกกับฉัน?


ทั้งหมดขึ้นอยู่กับสิ่งที่คุณทำ หากคุณกำลังพยายามทำสิ่งที่ง่ายมันก็สูงมาก คุณไม่ควรมีอัตราส่วนนั้นใน "hello world" ตัวอย่างเช่น
cwallenpoole

คำตอบ:


48

อะไรคือความซับซ้อนของวงจรที่บอกกับฉัน?

ความซับซ้อนของวงจรไม่ได้วัดจากบรรทัดของรหัส แต่จำนวนของเส้นทางที่เป็นอิสระผ่านโมดูล ความซับซ้อนของวงจร 17,754 หมายความว่าใบสมัครของคุณมี 17,754 เส้นทางที่ไม่ซ้ำกัน สิ่งนี้มีความหมายบางประการโดยทั่วไปแล้วในแง่ของความยากในการทำความเข้าใจและทดสอบใบสมัครของคุณ ตัวอย่างเช่นความซับซ้อนของวัฏจักรเป็นจำนวนกรณีทดสอบที่จำเป็นเพื่อให้ได้ความครอบคลุมสาขา 100% โดยถือว่าการทดสอบเป็นลายลักษณ์อักษรที่ดี

เป็นจุดเริ่มต้นที่ดีอาจจะเป็นบทความวิกิพีเดียกับความซับซ้อน cyclomatic มีคู่ของ snippits ของ pseudocode และกราฟบางอย่างที่แสดงความซับซ้อนของวัฏจักร หากคุณต้องการทราบข้อมูลเพิ่มเติมคุณสามารถอ่านกระดาษ McCabe ที่เขากำหนดความซับซ้อน

แอปพลิเคชันของฉันมีความซับซ้อนแบบ Cyclomatic จำนวน 17,754 บรรทัด แอปพลิเคชันนั้นมีรหัสเพียง 37,672 บรรทัด มันถูกต้องหรือไม่ที่จะบอกว่าความซับซ้อนนั้นสูงมากตามบรรทัดของโค้ด?

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

มันอาจเป็นเรื่องปกติที่จะมีความซับซ้อนของวัฏจักรสูงขึ้น ฉันขอแนะนำให้วัดความซับซ้อนของวัฏจักรในคลาสหรือระดับวิธีแทนที่จะเป็นเพียงระดับแอปพลิเคชัน นี่เป็นแนวคิดที่จัดการง่ายกว่านี้ฉันคิดว่ามันง่ายกว่าที่จะเห็นภาพหรือกำหนดเส้นทางผ่านวิธีการมากกว่าเส้นทางผ่านแอปพลิเคชันขนาดใหญ่


36

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

ตัวเลขมีประโยชน์ในระดับวิธีการ ในระดับที่สูงขึ้นมันเป็นเพียงตัวเลข

จำนวน 17,754 หมายถึงความซับซ้อนระดับโครงการ (รหัสทั้งหมด) ซึ่งไม่มีความหมายมากนัก

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

พิจารณาCASEคำสั่งที่มี 50 รายในหนึ่งวิธี บางทีแต่ละรัฐอาจมีตรรกะทางธุรกิจที่แตกต่างกัน นั่นจะสร้างความซับซ้อนของวงจร 50 คะแนนมี 50 คะแนนการตัดสินใจ คำสั่ง CASE อาจต้องได้รับการออกแบบใหม่โดยใช้รูปแบบจากโรงงานเพื่อกำจัดลอจิกการแตกกิ่ง บางครั้งคุณสามารถ refactor (แบ่งวิธีเป็นส่วนย่อย ๆ ) และในบางกรณีการออกแบบใหม่เท่านั้นที่จะลดความซับซ้อน

โดยทั่วไปสำหรับความซับซ้อนระดับวิธี:

  • <10 บำรุงรักษาง่าย
  • 11-20 ยากที่จะรักษา
  • ผู้สมัครที่มีอายุ 21 ปีขึ้นไปสำหรับการปรับโครงสร้าง / ออกแบบใหม่

นอกจากนี้ให้พิจารณาว่าความซับซ้อนที่สูงขึ้นทำให้รหัสทดสอบหน่วยยากขึ้น

ความซับซ้อนสูงสุดที่ฉันเคยเห็นในวิธีการเดียวคือ 560 มันเป็นเรื่องเกี่ยวกับ 2,000 บรรทัดของคำสั่งในหนึ่งวิธี โดยทั่วไปไม่สามารถทำลายได้ไม่สามารถทดสอบได้เต็มไปด้วยข้อบกพร่องที่อาจเกิดขึ้น ลองนึกภาพกรณีทดสอบหน่วยทั้งหมดที่จำเป็นสำหรับตรรกะการแตกแขนงนั้น! ไม่ดี.

ลองใช้วิธีการทั้งหมดที่อายุต่ำกว่า 20 และตระหนักว่ามีค่าใช้จ่ายในการปรับโครงสร้างวิธีการใด ๆ เพื่อให้ซับซ้อนน้อยลง


นี่เป็นคำตอบที่ดีกว่า
Pacerier

2
@Pacerier ในกรณีนั้นเพียงโหวตคำตอบ;)
Zero3

> "โดยทั่วไปสำหรับความซับซ้อนระดับวิธีการอ้างอิง"
Benny Bottema

หนึ่งในแอพพลิเคชั่นดั้งเดิมของ McCabe คือการจำกัดความซับซ้อนของรูทีนระหว่างการพัฒนาโปรแกรม เขาแนะนำว่าโปรแกรมเมอร์ควรนับความซับซ้อนของโมดูลที่กำลังพัฒนาและแบ่งออกเป็นโมดูลขนาดเล็กเมื่อใดก็ตามที่ความซับซ้อนของโมดูลเกิน 10
Jon Jonnnor

"คำสั่ง CASE อาจต้องได้รับการออกแบบใหม่โดยใช้รูปแบบจากโรงงานเพื่อกำจัดตรรกะการแตกแขนง" ทำไม? นั่นไม่ได้กำจัดความซับซ้อนของตรรกะ มันซ่อนมันและทำให้มันชัดเจนน้อยลงและทำให้ยากต่อการบำรุงรักษา
Mason Wheeler

1

มันคือจำนวนเส้นทางที่แตกต่างในแอปพลิเคชันของคุณ ตรวจสอบบทความนี้บน IBM CC

ดูเหมือนว่าจะสูง แต่ในกรณีของคุณมันคือการเพิ่ม CC ของวิธีการทั้งหมดของการเรียนและวิธีการทั้งหมดของคุณ ตัวอย่างของฉันถูกยืดออกไปมากเนื่องจากฉันไม่รู้ว่าโค้ดของคุณมีโครงสร้างอย่างไร แต่คุณก็อาจมีวิธีการมอนสเตอร์ที่มีรหัส 37672 บรรทัดหรือ 3767 วิธีซึ่งมีรหัสประมาณ 10 บรรทัด สิ่งที่ฉันหมายถึงคือในระดับแอปพลิเคชันตัวบ่งชี้นี้ไม่ได้มีความหมายมากนัก แต่ในระดับวิธีการอาจช่วยให้คุณปรับ / เขียนรหัสของคุณเป็นวิธีที่เล็กลงเพื่อลดความผิดพลาดได้ง่าย

สิ่งที่ฉันได้อ่านเป็นการส่วนตัวหลายครั้งคือวิธีการที่มีค่า CC สูงกว่า 10 มีความเสี่ยงสูงกว่าของข้อบกพร่อง

ฉันใช้Sonarเพื่อทดสอบคุณภาพรหัสของแอปพลิเคชันของฉันและโดยค่าเริ่มต้นฉันคิดว่ามันจะส่งสัญญาณเตือนหากคุณมีวิธีการที่มี +10 CC ยังคงอาจหมายถึงอะไร ตัวอย่างหนึ่งที่เป็นรูปธรรม: หากคุณใช้ Eclipse เพื่อสร้างequalsวิธีการตามคุณสมบัติของถั่วของคุณ CC จะไปอย่างรวดเร็วเหนือหลังคา ...


1
การตั้งค่าเริ่มต้นของ PMD คือการแจ้งเตือนถึงความซับซ้อนของวัฏจักรที่ 10 เช่นกัน การดูความซับซ้อนในระดับต่อวิธียังช่วยให้คุณไม่สนใจวิธีที่อาจมีเหตุผลที่ดีสำหรับ CC สูงเช่นequalsวิธีที่สร้างขึ้น
Thomas Owens

ฉันไม่แน่ใจดังนั้นฉันจึงตรวจสอบ แต่ Sonar ใช้ PMD ภายในเพื่อรับมาตรการนี้ ดังนั้นมันจึงสมเหตุสมผล :-)
Jalayn

-1

มันไม่เกี่ยวกับเครื่องมือที่คุณใช้ เครื่องมือโอเพนซอร์สบางตัวใช้คลาสเป็นโมดูลหรือโครงสร้างระดับอื่นเป็นโมดูล ดังนั้นยิ่งโครงการใหญ่มากเท่าใด Cyclomatic Complexity ก็จะยิ่งสูงขึ้นเท่านั้น อย่างไรก็ตามเพื่อความเข้าใจส่วนตัวของฉันมันควรจะอยู่บนพื้นฐานของฟังก์ชั่น เนื่องจากโครงการขนาดใหญ่ได้รับฟังก์ชั่นที่เข้าร่วมจะมี

ฉันแนะนำให้คุณใช้เครื่องมือที่เรียกว่า Lizard และคุณสามารถค้นหารหัสทรัพยากรและดาวน์โหลดไฟล์ zip ที่ github นอกจากนี้ยังมีเวอร์ชันออนไลน์หากไม่มีข้อมูลที่เป็นความลับในรหัสของคุณ

CCN ที่มีความหมายที่คุณควรใส่ใจนั้นอยู่บนพื้นฐานฟังก์ชั่นนอกเหนือจากอื่น ๆ นอกจากนี้การรักษา CCN Unber 15 ของแต่ละฟังก์ชั่นจะเป็นช่วงที่เหมาะสมที่สุด

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.