반복적 방법은 순환 복잡성을 줄이고 지원 가능성을 향상 시킵니까?


11

C #, JavaScript 및 Java 8과 같은 현대 언어에서 일반적으로 사용되는 반복적 인 방법은 코드의 이해도 및 지원 가능성에 대한 순환 복잡성의 영향을 줄입니까?

예를 들어 C #에는 다음 코드가있을 수 있습니다.

List<String> filteredList = new List<String>();

foreach (String s in originalList){
   if (matches(s)){
      filteredList.add(s);
   }
}

이것은 2의 단순한 순환 복잡도를 갖습니다.

이것을 다음과 같이 쉽게 다시 작성할 수 있습니다.

List<String> filteredList = originalList.where(s => matches(s));

순환 순환 복잡도는 0입니다.

이것이 실제로 더 지원 가능한 코드를 생성합니까? 이 주제에 대한 실제 연구가 있습니까?


2
제목은 순환 복잡성 감소에 대해 요구하지만 텍스트는 CC 감소를 가정하고 유지 관리성에 대해 묻습니다. 중요한 질문이 될 가능성이 있습니다. 제목을 더 정확하게 편집 할 수 있습니까?
Kilian Foth

@KilianFoth 더 나은가요?
C. Ross

반복적 방법을 반복적 개발 방법론과 연관시킬 것입니다. 더 나은 용어는 고차 함수라고 생각합니다. (그리고 옆으로, 메소드에는 리턴 유형 / 무효가 없지만 함수는 무언가를 리턴합니다).
Johannes Rudolph

@JohannesRudolph "메소드는 리턴 타입 / 보이드가없고 함수는 무언가를 리턴합니다"-어떤 언어로되어 있습니까? 나는 이것을들은 적이 없다. 사실, 내가 들어 본 유일한 차이점은 메소드는 클래스와 연관되어 있고 함수는 그렇지 않다는 것입니다.
THREED

답변:


14

내 생각에 당신은 단지 복잡성을 나눈 것입니다. .where()CC에서 구현을 계산하지 않기 때문에 감소했습니다 .

전체 CC는 실제로 이동하지 않았으며 이제 코드 의 CC가 프레임 워크의 코드로 이동했기 때문에 CC가 감소했습니다.

유지 관리가 더 쉽다고 말하고 싶습니다. 언어의 특징 인 경우 사용하십시오. 당신이 사용 하는 "아, 나는 영리한 속임수" 가 아니며 단순한 인라인 리 듀스 유사 함수입니다.


11

사이 클릭 복잡성의 결함을 메트릭으로 강조 표시하는 것만으로 코드의 복잡성이 실제로 변경되지 않았습니다. 첫 번째 예에는 명시적인 분기가 있으며 두 번째 예에는 내포 된 분기가 있음을 이해해야합니다. 두 번째는 구문을 이해하고 문제가 될 수있는 기본 구문이 덜 사용되므로 명확하고 이해하기 쉽습니다.


1
where여기서는 프레임 워크에서 비롯된 것이기 때문에 자체 코드의 순환 복잡성이 줄어든다고 주장 할 수 있습니다. 함수를 여러 개로 나누면 시스템의 전체적인 복잡성이 감소하지는 않지만 (실제로는 약간만 증가하더라도) 증가하는시기를 결정하는 데 도움이되기 때문에 사이클로 매틱 복잡도는 여기에서도 유용합니다. 시스템의 일부가 지나치게 복잡 해져서 분해해야합니다.
THREED

6

질문에 객관적으로 대답하기 위해서는 유지 관리 성을위한 일종의 메트릭이 필요합니다. 복잡성을 자체는 유지 보수의 측정 아니지만, 그것은 이다 취지가 유지 보수성을 측정하는 몇 가지 지표의 구성 요소. 예를 들어, 유지 보수성 지수 의 공식 은 다음과 같습니다.

MI = 171 - 5.2 * ln(V) - 0.23 * (G) - 16.2 * ln(LOC)

G문제가되는 코드의 순환 복잡성은 어디에 있습니까 ? 따라서 코드 조각의 순환 복잡성을 줄이면 정의에 따라 코드의 유지 관리 가능성 색인과 유사하게 순환 복잡도를 사용하는 기타 메트릭이 향상 됩니다.

그것은 당신이 제안하는 변화의 종류는 프로그램이 만들어 여부를 말하기 힘들 것 같다 프로그래머에 더 많은 유지 보수; 그것은 아마도 그들이 당신의 where방법 에 얼마나 익숙한 지에 달려 있습니다.


경고 : 매직 넘버! (>_<)
이즈 카타

유지 관리 성 지수에는이 작은 문제가 있습니다. 그것의 세 가지 구성 요소는 Halstead Volume, Cyclomatic Complexity 및 Lines of Code입니다. Halstead Volume과 Cyclomatic Complexity는 Lines of Code와 매우 밀접한 상관 관계가있는 것으로 나타났습니다. 이는 코드 라인에만 의존하는 유지 보수성 지수에 대한 대체 근사 방정식이 계산 난이도가 훨씬 낮지 만 원본과 거의 동일한 정확도를 얻을 수 있음을 의미합니다.
John R. Strohm

@ JohnR.Strohm LOC를 유지 관리 성 메트릭으로 사용하더라도 비슷한 결과를 얻을 수 있다고 생각합니다. OP의 변화는 LOC를 4에서 1로 감소시키고, 순환 복잡성을 감소시키는 다른 변화도 마찬가지로 LOC를 감소시킬 가능성이 있습니다. 어느 쪽이든, 실제로 유지 관리 성을 정의하고 측정하는 방법에 달려 있습니다.
Caleb

1
@Caleb : 동의합니다. 내가하려고하는 요점은 사람들이 너무 복잡한 메트릭과 메트릭 조합을 너무 자주 사용한다는 것입니다. 단지 모든 코드가 실제 코드에서 평범한 오래된 코드 라인 (LOC)과 강한 상관 관계가 있음을 알지 못합니다 따라서 LOC보다 더 예측 적이거나 설명적인 가치가 없습니다.
John R. Strohm

3

CC (cyclomatic complex)는 코드 크기와 매우 밀접한 상관 관계 가있는 것으로 밝혀 졌기 때문에 "CC는 그 자체로 설명력이 전혀 없다"고 말할 수있다. 당신이 정말로 요구하는 것은 "C #, JavaScript와 같은 현대 언어에서 일반적으로 사용되는 것과 같은 반복적 인 메소드가 Java 8에서 (가능하면) 코드 크기가 코드의 이해 및 코드 지원에 미치는 영향을 줄이는 지 여부"입니다.

그 시점에서 답이 분명해지기를 바랍니다. 짧은 코드가 일반적으로 이해, 유지 보수 및 지원하기 쉽다는 것이 수십 년 동안 알려져왔다.


2

Cyclomatic Complexity의 원시 통계에 대해 이야기하고 있다면 반드시하십시오. 방금 2에서 0으로 좁혔습니다. 숫자, 순수한 게인으로 가려면 끝까지 가십시오.

실용적 (읽기 : 인간) 관점에서, 실제로 복잡성을 2 증가 했다고 주장 할 것입니다 . 한 가지 요점은 이제 다른 프로그래머가이를 이해하기 위해 유창한 구문 LINQ에 대한 지식을 가져 오거나 얻어야한다는 사실에서 비롯됩니다 암호.

난이도가 증가하는 또 다른 점은 Lambda Expressions를 이해하는 것입니다. 람다는 매우 간단하지만 이 경우에 , 완전히 그들에게 감사를 만들 수있는 몇 가지 패러다임의 변화가있다.

이 사례를 사용 a.where(x => matches(x, arg))하는 것은 끔찍하지 않으며, 정직하게도 일부 동료가 처음으로 LINQ 및 Lambda 표현식을보고 작업 할 수있는 좋은 방법입니다. 다른 코드들도 큰 효과를 볼 수 있습니다.) 그러나 이것들을 사용하려면 약간의 지식이 필요합니다.

LINQ 리 팩터가 실제로 foreach루프가되는 것보다 읽기가 훨씬 더 나쁜 경우를 보았으므로주의를 기울이는 것이 좋습니다 .


1

주관적으로, 그것은 람다 표현을 이해한다면 개발자 청중에 달려 있습니다.

List<String> filteredList = originalList.where(s => matches(s));

이해하는 것이 더 빠르며 약간 더 쉽습니다. s 및 matches () 사용에 대해 더 걱정할 것입니다. 자기 설명적인 것도 아닙니다.

List<String> filteredList = 
    originalList.where(stringToBeTested => matchesNameTest(stringToBeTested));

또는

List<String> filteredList = 
        originalList.where(originalListString => matchesNameTest(originalListString));

matches () 함수로 뛰어 들어 수행중인 일치를 판별하지 않고도 개발자에게보다 의미있는 정보를 제공하고 분석하기가 더 쉽습니다.

유지 관리 성은 코드를 이해하는 능력뿐만 아니라 코드를 이해할 수있는 속도와 정확성에 관한 것입니다.


2
에이스 구조를 강조하기 위해 의도적으로 의미 론적 내용이없는 예입니다.
C. Ross
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.