문제

최근에 우리 회사는 코드의 기능의 사이클로 음성 복잡성 (CC)을 매주 코드로 측정하기 시작했으며 어떤 기능이 개선되거나 악화되었는지보고했습니다. 그래서 우리는 CC의 기능에 더 많은 관심을 기울이기 시작했습니다.

CC는 함수의 결정 지점 (예 : IF 문, 루프, 선택 등) 또는 함수를 통한 경로 수를 1 +로 비공식적으로 계산할 수 있음을 읽었습니다.

CC를 줄이는 가장 쉬운 방법은 추출 방법을 반복적으로 리팩토링하는 것입니다 ...

내가 확실하지 않은 것들이 있습니다. 예를 들어 다음 코드 조각의 CC는 무엇입니까?

1)

for (int i = 0; i < 3; i++)
    Console.WriteLine("Hello");

그리고

Console.WriteLine("Hello");
Console.WriteLine("Hello");
Console.WriteLine("Hello");

둘 다 똑같은 일을하지만 첫 번째 버전은 For 문으로 인해 CC가 더 높습니까?

2)

if (condition1)
    if (condition2)
        if (condition 3)
            Console.WriteLine("wibble");

그리고

if (condition1 && condition2 && condition3)
    Console.WriteLine("wibble");

언어가 C#과 같은 단락 평가를한다고 가정하면,이 두 코드 조각은 동일한 효과를 가지고 있지만 첫 번째 조각의 CC는 3 개의 결정 지점/IF 문이 있기 때문에 더 높습니까?

3)

if (condition1)
{
    Console.WriteLine("one");

    if (condition2)
        Console.WriteLine("one and two");
}

그리고

if (condition3)
    Console.WriteLine("fizz");

if (condition4)
    Console.WriteLine("buzz");

이 두 코드 조각은 다른 일을하지만 동일한 CC를 가지고 있습니까? 아니면 첫 번째 조각의 중첩 된 IF 문에 CC가 더 높습니까? IE NEVERDED IF 진술은 정신적으로 이해하기가 더 복잡하지만 CC에 반영 되는가?

도움이 되었습니까?

해결책

  1. 예. 첫 번째 예제에는 의사 결정 지점이 있고 두 번째 예는 그렇지 않으므로 첫 번째는 CC가 더 높습니다.
  2. 예-메이 베, 첫 번째 예제에는 여러 가지 결정 지점이있어 CC가 더 높습니다. (설명은 아래를 참조하십시오.)
  3. 예 메이베. 분명히 그들은 같은 수의 의사 결정 지점을 가지고 있지만 CC를 계산하는 방법에는 다른 방법이 있습니다.

... 회사가 특정 방식으로 CC를 측정하는 경우 해당 방법에 익숙해 져야합니다 (이를 위해 도구를 사용하고 있기를 바랍니다). 다른 상황 (사례 명세서, 부울 연산자 등)에 대해 CC를 계산하는 방법에는 여러 가지가 있지만 사용하는 규칙에 관계없이 메트릭에서 동일한 종류의 정보를 얻어야합니다.

더 큰 문제는 다른 사람들이 언급 한 것입니다. 귀하의 회사는 CC보다 CC에 더 집중하고있는 것 같습니다. 일반적으로 5 미만은 크고 10 미만은 좋으며 20 미만은 괜찮습니다. 21 ~ 50은 경고 신호가되어야하며 50 이상은 큰 경고 신호이어야하지만 절대 규칙이 아닌 가이드입니다. CC가 50을 초과하는 절차에서 코드를 검사하여 많은 코드 더미가 아니라 절차가 그렇게 쓰여진 특정 이유가있을 수 있습니다. 숫자) 리팩터링하는 이유.

CC를 줄이기 위해 도구를 사용하여 코드를 리팩터링하는 경우 도구가 수행하는 작업을 이해하고 단순히 하나의 문제를 다른 곳으로 바꾸지 않도록하십시오. 궁극적으로, 당신은 당신의 코드가 결함이 적고, 제대로 작동하고, 유지하기가 쉽기가되기를 원합니다. 해당 코드에도 CC가 낮 으면 좋습니다. 코드가 이러한 기준을 충족하고 CC가 10 이상인 경우, 가능한 모든 관리와 함께 앉아 코드를 방어 할 때 (그리고 아마도 정책을 검사하도록 할 수 있습니다).

다른 팁

Wikipedia 항목을 통해 탐색 한 후 Thomas J. McCabe의 원본 종이, 위에서 언급 한 항목은 메트릭에 문제가있는 것 같습니다.

그러나 대부분의 지표에는 장단점이 있습니다. 나는 충분히 큰 프로그램에서 CC 값이 지적 할 수 있다고 생각합니다. 아마도 복잡 할 수 있습니다 코드의 일부. 그러나 CC가 높다고해서 반드시 복잡한 것은 아닙니다.

모든 소프트웨어 메트릭과 마찬가지로 CC는 완벽하지 않습니다. 충분히 큰 코드베이스에 사용되면 어디에 있는지에 대한 아이디어를 줄 수 있습니다. ~할 것 같다 문제가있는 영역이 되십시오.

여기에는 명심해야 할 두 가지가 있습니다.

  1. 충분히 큰 코드베이스 : 모든 비 사소한 프로젝트에서는 CC 값이 실제로 높은 기능을 갖게됩니다. 예제 중 하나에서 CC가 2 또는 3이 될지 여부는 중요하지 않습니다. CC가있는 기능은 300 개 이상의 CC가있는 기능은 분명히 분석해야 할 것입니다. CC가 301 또는 302인지 상관 없습니다.
  2. 머리를 사용하는 것을 잊지 마십시오. 많은 결정 지점이 필요한 방법이 있습니다. 종종 그들은 어떻게 든 적은 수의 사람들을 확보 할 수 있지만 때로는 할 수 없습니다. "CC> XY를 사용하여 모든 메소드를 리팩터링하기"와 같은 규칙을 사용하지 마십시오. 그들을보고 두뇌를 사용하여 무엇을 해야하는지 결정하십시오.

나는 주간 분석의 아이디어를 좋아합니다. 품질 관리에서 트렌드 분석은 문제를 인출하는 데 매우 효과적인 도구입니다. 창조 중에. 이것은 그들이 너무 커질 때까지 기다려야하는 것보다 훨씬 낫습니다. SPC 자세한 내용은).

CC는 품질을 측정하기위한 만병 통치약이 아닙니다. 루프가 CC가 더 큰 경우에도 반복 된 진술은 루프보다 "더 나은"상태가 아닙니다. 루프가 CC가 더 큰 이유는 때로는 실행 될 수 있고 때로는 실행되지 않을 수도 있기 때문에 두 가지 다른 "사례"로 이어지기 때문입니다. 귀하의 경우 루프가 있습니다 언제나 상수를 사용하기 때문에 세 번 실행되지만 CC는 이것을 감지하기에 충분히 영리하지 않습니다.

예 2의 사슬 된 IFS와 동일합니다.이 구조를 사용하면 조건 1과 조건 2 만 참이면 실행되는 문장을 가질 수 있습니다. 이것은 &&를 사용하는 경우에 불가능한 특별한 경우입니다. 따라서 IF 체인은 코드에서 이것을 사용하지 않더라도 특별한 경우에 더 큰 잠재력을 가지고 있습니다.

이것이 적용 할 위험입니다 어느 맹목적으로 메트릭. CC 메트릭은 확실히 많은 장점이 있지만 코드를 개선하기위한 다른 기술과 마찬가지로 상황에서 이혼 한 것으로 평가할 수 없습니다. Casper Jone의 코드 측정 라인에 대한 토론에서 경영진을 지적하십시오 (링크를 찾을 수 있기를 바랍니다). 그는 코드 라인이 생산성의 좋은 척도라면 어셈블러 언어 개발자는 지구상에서 가장 생산적인 개발자라고 지적합니다. 물론 그들은 다른 개발자들보다 더 생산적이지 않습니다. 소스 코드가 적은 고급 언어가 수행하는 일을 달성하기 위해 훨씬 더 많은 코드가 필요합니다. 내가 말했듯이, 나는 당신이 당신의 관리자들에게 메트릭이 당신에게 말하는 것을 지능적으로 검토하지 않고 맹목적으로 지표를 적용하는 것이 얼마나 멍청한지를 보여줄 수 있습니다.

그렇지 않은 경우, 귀하의 경영진은 CC 측정을 더 검토 해야하는 코드에서 잠재적 인 핫스팟을 발견하는 방법으로 CC 측정을 사용하는 것이 현명하다고 제안합니다. 코드 유지 관리 가능성이나 다른 좋은 코딩 측정에 대한 참조없이 CC가 낮은 CC의 목표를 맹목적으로 목표로하는 것은 어리석은 일입니다.

순환 복잡성은 온도와 유사합니다. 그것들은 모두 측정 값이며 대부분의 경우 맥락없이 의미가 없습니다. 내가 외부 온도가 72도라고 말하면 많은 의미는 아닙니다. 그러나 내가 북극에 있다는 사실을 추가하면 숫자 72가 중요해집니다. 누군가가 나에게 방법이 10이라고 말하면, 그것이 맥락없이 좋은지 나쁜지 판단 할 수 없습니다.

기존 애플리케이션을 검토 할 때 Cyclomatic Complexity는 유용한 "시작점"메트릭입니다. 내가 가장 먼저 확인하는 것은 CC> 10의 방법입니다. 이러한 "> 10"방법이 반드시 나쁘지는 않습니다. 그들은 단지 코드를 검토하기위한 시작점을 제공합니다.

CC 번호를 고려할 때 일반 규칙 :

  • 테스트의 CC #과 #의 관계는 CC # <= #tests 여야합니다.
  • CC#에 대한 리팩토러는 유지 관리 가능성을 높이는 경우에만
  • 10 이상의 CC는 종종 하나 이상을 나타냅니다 코드 냄새

Off Topic] 메트릭에서 좋은 점수보다 가독성을 선호한다면 (J.Spolsky가 "측정 된 것, GET가 끝나는가? 잘 알려진 부울을 사용하여 복잡한 조건부 명세서를 대체하십시오.

그 다음에

if (condition1 && condition2 && condition3)
    Console.WriteLine("wibble");

~이 되다

bool/boolean theWeatherIsFine =  condition1 && condition2 && condition3;

if (theWeatherIsFine)
    Console.WriteLine("wibble");

나는이 주제에 대한 전문가는 아니지만 나는 2 센트를 줄 것이라고 생각했다. 그리고 아마도 그게 전부 일 것입니다.

사이클로틱 복잡성은 문제가있는 코드 스 니펫을 찾는 데있어서의 특정 자동 지름길 인 것 같습니다. 그러나 테스트 중 하나를 해결하는 것이 실제 문제가 아닌가? 코드에는 몇 개의 테스트 케이스가 필요합니까? CC가 높지만 테스트 사례 수가 동일하고 코드가 더 깨끗하다면 CC에 대해 걱정하지 마십시오.

1.) 결정 지점이 없습니다. 프로그램을 통한 하나의 경로는 하나이며 두 버전 중 하나만 가능한 한 가지 결과 만 있습니다. 첫 번째는 더 간결하고 더 나은 순환 복잡성이 저주받습니다.

둘 다에 대한 1 개의 테스트 사례

2.) 두 경우 모두 "wibble"을 쓰거나 그렇지 않습니다.

둘 다에 대한 2 개의 테스트 사례

3.) 먼저 "하나"또는 "하나"및 "하나와 둘"을 초래할 수 없습니다. 3 개의 경로. 두 번째는 둘 중 하나 또는 둘 중 하나를 초래할 수 없습니다. 4 경로.

두 번째 테스트 사례에 대한 3 가지 테스트 사례

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top