핵심 요약
- 순환 복잡도(CC)는 메서드 내 독립적인 실행 경로 수를 측정하며 완전한 테스트를 위한 최소 케이스 수를 나타냅니다.
- C#에서는 if, 반복문, switch의 case, &&/|| 연산자 등이 점수를 올리지만 else나 try는 점수에 포함되지 않습니다.
- 권장 상한선은 대략 10점이며, 중첩 분기로 복잡도가 높아진 메서드는 단일 책임을 가진 하위 메서드로 쪼개어 해결할 수 있습니다.
요약 순환 복잡도(Cyclomatic Complexity, CC)는 코드 내에서 독립적으로 실행될 수 있는 실행 경로의 수를 측정하는 대표적인 소프트웨어 품질 지표입니다. 1976년 토마스 J. 매케이브(Thomas J. McCabe)가 그래프 이론을 기반으로 고안한 개념으로, 프로그램의 제어 흐름 그래프에서 노드(명령문 블록)와 엣지(분기 및 점프)의 관계식(M = E - N + 2P)을 통해 도출됩니다. 일반적인 단일 진입·단일 종료 메서드에서는 '1 + 분기문의 수'라는 직관적인 공식으로 계산됩니다.
C# 환경에서 순환 복잡도를 증가시키는 구문은 if, while, for, foreach, case, default, continue, goto, &&, ||, catch, 삼항 연산자(?:), 널 병합 연산자(??), 그리고 최신 C#의 and, or 같은 패턴 매칭 구문들입니다. 반면 else는 if에 의해 이미 분기가 생성된 것으로 간주되어 복잡도를 올리지 않으며, do, switch 키워드 자체, try, using, throw, finally, return, 객체 생성 등도 카운트에서 제외됩니다. switch 문의 경우 키워드 자체가 아닌 각 case와 default 라벨마다 1점씩 가산됩니다.
이 지표가 중요한 이유는 메서드의 모든 경로를 완전히 테스트하기 위해 필요한 최소한의 테스트 케이스 수를 의미하기 때문입니다. 복잡도 점수가 1점이면 분기 없는 단일 경로를 뜻하고, 전통적으로 10점 안팎이 권장 상한선으로 여겨집니다. 마이크로소프트의 CA1502 정적 분석기에서는 25점을 초과하는 메서드를 과도하게 복잡한 코드로 경고합니다.
실제 C# 예시 코드에서는 중첩된 if문 6개와 논리 연산자 && 1개가 얽혀 복잡도 8점을 기록한 주문 처리 메서드를 다룹니다. 이는 최소 8개의 테스트가 필요하며 비즈니스 로직 수정 시 버그가 발생하기 쉬운 위험 신호입니다. 글에서는 이를 유효성 검사, 주문 유형 처리, 할인 적용 등 복잡도가 낮은 독립된 소형 메서드들로 리팩터링하여 코드의 가독성과 안전성을 확보하는 접근 방식을 소개합니다.
Sponsored · 광고