코드에서 단순성을 어떻게 정의하고 측정 할 수 있습니까?


13

코드의 단순성에 대한 나의 정의와 이해가 틀렸을 가능성을 이해하는 데 도움이 되는 가독성과 관련된 단순성 에 대한 이전 질문에는 많은 답변이 있습니다 .

코드에서 단순성을 어떻게 정의 할 수 있습니까? 코드 단순성을 측정하기 위해 어떤 소프트웨어 측정 및 메트릭을 사용할 수 있습니까?


2
@MarkTrapp 경험적 소프트웨어 엔지니어링의 주제, 익숙하지 않은 주제없이 코드 단순성을 논의하는 다른 방법이 있습니다. 예를 들어, 자동화 된 테스트를 작성하는 능력의 측면에서 단순성을 논의합니다. 저의 기술과 지식을 통해 경험적인 소프트웨어 엔지니어의 관점에서이 질문에 대답 할 수 있지만 다른 관점에서는 다른 관점에서 대답 할 수 있습니다. 질문에 해당 설명을 추가하면 유용한 답변 수가 크게 제한되어 너무 많이 현지화됩니다 (IMO). 추가하고 싶다면 할 수 있지만, 이것은 좋은 질문입니다.
Thomas Owens

2
@ThomasOwens 실제 질문에는 아이디어 나 의견이 아니라 답이 있습니다 . 범위를 좁 히면 모든 사람이 같은 방식으로 질문에 대답하는 방법이 Stack Exchange와 정확히 일치합니다. 문제를 해결하는 방법은 여러 가지가있을 수 있지만 명확하게 설명 된 문제는 하나뿐입니다.

현재 상태 에서이 질문에 대한 답변은 거의 없습니다 (제 답변은 경험적 소프트웨어 엔지니어링 관점을 다루며 일반적인 메트릭으로 아마도 다른 것들이 있습니다). 다른 관점에서 유효한 대안을 제공하는 답변을 배제하는 것은 의미가 없습니다.이 질문의 말이합니다. 이러한 수정 사항에 전적으로 동의하지 않으며 질문은 원래 형식으로 되돌려 야합니다.
Thomas Owens

@MarkTrapp 문제는 명백합니다. 코드 단순성을 어떻게 결정합니까? 몇 가지 좋은 답변이 있습니다. 광산은 경험적 소프트웨어 엔지니어링 기술을 사용하여 복잡성을 측정합니다. 또 다른 방법은 자동화 된 테스트를 작성하는 것이 좋으며 좋은 테스트를 작성하기 어려운 경우 코드가 복잡하여 완벽하게 유효한 답변입니다. 내가 모르는 다른 사람들이있을 수 있습니다. 코드베이스의 복잡성 / 간단 성을 측정해야하는 경우 모든 대안을 제시 할 수있는 방식으로 질문을 작성해야합니다. 그러면 질문자가 특정 사례에 가장 적합한 솔루션을 선택할 수 있습니다.
Thomas Owens

답변:


16

복잡성 (또는 단순성과 복잡성의 반대라고 생각하는 경우 단순성)을 측정하는 가장 일반적인 측정 기준은 McCabe의 Cyclomatic ComplexityHalstead Complexity Metrics 입니다.

순환 복잡도는 클래스에서 계산 될 수 있지만 주어진 단위, 일반적으로 메서드 또는 함수를 통해 고유 한 경로 수를 측정합니다. 경로 수가 증가함에 따라 작업 메모리 개념과 관련된 주어진 모듈을 통한 데이터 흐름을 기억하기가 더 어려워집니다 . 사이클로 메틱 복잡도가 높으면 모듈을 테스트하는 데 어려움이 있음을 나타냅니다. 시스템을 통한 다양한 경로를 다루기 위해서는 더 많은 테스트 사례가 필요합니다. 사이클로 메틱 복잡성이 높고 결함률이 높은 연구도있었습니다. 일반적으로 10의 순환 복잡도는 단위를 검토하고 리팩토링해야 함을 나타냅니다.

Halstead의 복잡성 측정은 전체 및 별개의 연산자 및 피연산자의 입력을 사용하여 코드의 양, 난이도 및 노력을 계산합니다. (고유 연산자 수 / 2) * (총 피연산자 수 / 고유 피연산자 수) 인 난이도는 시스템 학습 또는 코드 검토 수행과 같은 작업에 대한 코드를 읽고 이해하는 능력과 관련이 있습니다. 다시 시스템 레벨, 클래스 레벨 또는 메소드 / 함수 레벨에서이를 계산할 수 있습니다. 여기여기에서 이러한 측정을 계산하는 방법에 대한 몇 가지 게시물이 있습니다 .

코드 줄을 세는 것만으로도 복잡한 아이디어를 얻을 수 있습니다. 더 많은 코드 줄은 모듈에서 읽고 이해해야 할 것이 더 많다는 것을 의미합니다. 이것을 독립형 측정으로 사용하는 것을 망설입니다. 대신 결함 밀도를 얻기 위해 주어진 모듈의 결함 수와 같은 다른 측정과 함께 사용합니다. 결함 밀도가 높으면 테스트 작성 및 코드 검토 수행에 문제가있을 수 있으며 이는 복잡한 코드로 인해 발생하거나 발생하지 않을 수 있습니다.

팬인 및 팬 아웃은 데이터 흐름과 관련된 두 가지 다른 메트릭입니다. 여기 에 정의 된 것처럼 fan in은 호출 된 프로 시저, 매개 변수 읽기 및 글로벌 변수 read 및 fan out은 지정된 프로 시저, 호출 된 매개 변수 (외부 사용자에게 노출, 참조로 전달)를 호출하는 프로 시저의 합계입니다. 그리고 전역 변수가 쓰여집니다. 다시 말하지만, 높은 팬인 및 팬 아웃은 이해하기 어려운 모듈을 나타냅니다.

특정 패러다임에는 유용한 다른 측정 또는 메트릭이있을 수 있습니다. 예를 들어, 객체 지향 세계에서 모니터링 커플 링 (욕망 낮음), 응집력 (욕망 높음) 및 상속 깊이 (욕망 낮음)를 사용하여 시스템이 얼마나 단순하거나 복잡한지를 평가할 수 있습니다.

물론 많은 측정 값과 측정 항목이 단순히 지표라는 것을 인식하는 것이 중요합니다. 단순성을 높이기 위해 리팩토링이 필요한지 또는 그렇게 할 가치가 없는지 판단하려면 판단을 사용해야합니다. 측정, 메트릭 계산 및 코드에 대해 배울 수 있지만 숫자로 시스템을 설계하고 싶지는 않습니다. 궁극적으로 말이되는 것을하십시오.


5
나는 당신이 그것을 언급했지만 사이클로 틱 복잡성은 실제로 함수 / 메소드 레벨에서만 유용하고 높은 레벨에서는 훨씬 더 주관적 / 쓸모가 없다는 것을 강조하는 것이 중요하다는 것을 알고 있습니다.
Ryathal

문제는 이러한 조치가 좋은 가이드이지만 일반적입니다. "나쁜"프로그램의 점수가 좋은 경우, 예를 들어 12 개의 함수, 두 개 이상의 매개 변수가있는 단일 함수로도 충분할 수 있으며, 복잡한 문제에 대한 솔루션으로 잘 작성된 많은 "좋은"프로그램이 점수를 매길 수 있습니다. 심하게.
James Anderson

@ 제임스 나는 분명히 지적했다. 모든 측정 또는 측정 항목은 무언가를 봐야한다는 지표로 맥락에서 취해야합니다. 수정 조치가 필요한지 여부와 해당 조치가 무엇인지 판별하려면 엔지니어의 판단이 필요합니다. 그러나 적극적으로 데이터를 수집하지 않는 한 잠재적 인 문제에 대해 경험적으로 알 수있는 방법은 없습니다.
Thomas Owens

7

단순성을 정의하는 공식 모드를 보는 대신 단순성을 코드 작성 품질의 속성으로 정의하고 싶습니다.

나는 약간의 단순성을 측정하지는 않지만 언제 간단한 것을 호출합니까?

1. 코드 탐색 : 코드를 탐색
하는 것이 얼마나 쉬운가요? API 함수가 작성된 위치를 쉽게 파악할 수 있습니까? 예를 들어 어떤 메소드가 다른 메소드를 호출하는지 (그리고 왜)-호출 흐름을 이해하는 것이 쉬운가?

코드 탐색이 용이 할 때, 코드는 간단한 따라하기.

2. 이름 지정
다른 코딩 표준은 코드를 더 깔끔하게 보이도록 도와줍니다. 가장 중요한 것은 클래스 / 객체 인스턴스 / 변수 / 방법의 이름 지정입니다. 명확하고 모호 이름을 사용 명확하게는에 큰 영향이 단순 코드를. 단순한 이름을 식별하기 어려운 경우, 해당 변수 / 방법이라는 아이디어를 다시 생각할 수 있습니다.

3. 해석 및 참조
각 분석법이 명확한 역할을 수행합니까? 각 변수 / 속성들이 그들이 담당하는 역할을 쉽게 결정할 수 있습니까? 코드가 가정을 암시하거나 관련없는 변수 세트에 영향을 미치는 작업을 수행하면 유지 관리의 악몽이 될 수 있습니다.

4. 의존성 또는 결합
코드를 살펴 보는 것만으로 판단하기는 어렵지만 누군가 버그를 고치려고하면 매우 분명해집니다. 다른 객체에서 다른 것들이 변경 되면 여기의 작업이 변경됩니까? 그러한 변화가 명백합니까? 물건을 수용하기 위해 API를 너무 자주 변경해야합니까? 이것은 모듈 간 관계가 간단 하지 않다는 것을 암시합니다

5. 입력 사용자 또는 애플리케이션
마지막으로 API / UI에서 사용자 입력 또는 애플리케이션이 얼마나 간단하게 받아 들여 집니까? 여러 가지 가능한 사용자 / 응용 프로그램 (다른 목적으로)이 귀하에게 제공해야하는 경우 – 분명합니까? 더 높은 추상화와 관련이 없지만 여전히 인터페이스의 앞뒤로가는 상태 / 세부 사항이 있습니까?

내가 일반적으로 묻는 간단한 질문은 다음과 같습니다. 프로그램 대신 사람이 수행하는 동일한 기능을 요청한 경우이 정보를 종이 양식으로 채웠 습니까? 그렇지 않다면, 나는 여기서 충분히 단순 하지 않다.

이 목록이 완전한 것은 아니지만, 기준은 소프트웨어를 사용하고 수정하는 것이 얼마나 쉬운 지 또는 어려운 것 같습니다. 간단합니다.


1
그는 측정과 측정을 요구했다. 이것들은 주관적이므로, 나는 그들이 요점이라고 생각하지 않습니다.
psr December

@psr 동의합니다. 그것은 또한 토마스의 대답으로부터의 대답에서 매우 분명했습니다. 그러나 그는 가독성과 관련된 단순성 을 언급 했다 . The Answer of Thomas는 Cyclomatic의 복잡성을 다루고 있습니다. 이것은 코드 를 테스트 하는 것이 얼마나 복잡하고 코드가 가독성 측면에서 얼마나 복잡하지 않고 유지 관리 성 을 확장 할 수 있는지를 알려줍니다 . 이것들은 매우 다른 두 가지 개념입니다. 정확히 필자가 모순을두기 위해이 답변을 쓴 이유는 무엇입니까? 불행히도 내 지식으로 는 가독성 측면에서 코드의 단순성 을 나타내는 메트릭이 없습니다 .
Dipan Mehta

"오해 하기 어려운 이름을 사용하십시오" -IMHO 이것은 너무 비현실적이고 불가능한 목표를 목표로합니다. 차라리 명확하게 표현하려고하지 않고 단순히 "명확하고 명확한 이름 사용"이라고 말하고 싶습니다.
Péter Török

@ PéterTörök 동의합니다. 필자는 많은 조직에서 매우 명확하게 정의 된 명명 규칙 규칙과 특정 변수 의 강렬 에 대한 약간의 혼동이 지속 된다고 생각합니다 . 따라서 목적의 명확성은 공식적인 규칙이 아닌 단순성에 달려 있다고 강조 했다. 내가 설명한 방식대로 배 밖으로 나갔을 수도 있습니다. 감사.
Dipan Mehta

@Dipan Cyclomatic의 복잡성은 작업 메모리를 통한 코드의 가독성과 관련이 있습니다. 순환 적 복잡성이 높거나 블록 깊이가 높은 코드는 작업 메모리에 보관하기가 어렵 기 때문에 직접 읽는 것이 더 어렵습니다.
Thomas Owens

0

코드 단순성에 대한 기존의 좋은 메트릭을 알지 못합니다 (존재하지 않는다는 의미는 아닙니다. 단지 알지 못합니다). 나는 몇 가지를 제안 할 수 있습니다. 어쩌면 일부는 도움이 될 것입니다.

  • 사용 된 언어 기능의 단순성 : 언어에 "고급"및 "간단한"것으로 간주되는 기능이있는 경우 고급 기능의 발생 횟수를 계산할 수 있습니다. "고급"을 정의하는 방법이 조금 더 주관적 일 수 있습니다. 나는 이것이 프로그램의 "영리함"을 측정하는 것과 같다고 말할지도 모른다. 일반적인 예 : ?:운영자가 "고급"기능이어야 한다고 말하고 다른 사람들은 동의하지 않을 수 있습니다. 이것을 테스트 할 수있는 도구를 작성하는 것이 얼마나 쉬운 지 모르겠습니다.

  • 프로그램 내 구성의 단순성 : 함수가 수용 할 매개 변수 수를 측정 할 수 있습니다. > m 매개 변수를 가진 모든 함수의 > n % 가있는 경우 nm 을 정의하는 방법 (n = 3 및 m = 6?)에 따라 단순 하지 않은 것으로 계산할 수 있습니다 . 나는 이것을 측정 할 수있는 정적 분석 도구가 있다고 생각합니다 .JTest는 단순히> m 매개 변수로 함수를 측정했다고 생각 합니다.

  • 중첩 루프 또는 제어 구조의 수를 세어 볼 수 있습니다. 이것은 실제로 나쁜 메트릭이 아니며 이름이 있다고 생각합니다 (머리 꼭대기를 기억할 수는 없습니다). 다시 말하지만, 이것을 측정 할 수있는 도구 (JTest와 같은 도구)가 어느 정도 있다고 생각합니다.

  • "리팩토링"을 측정 할 수 있습니다. 코드에 리팩토링 수 있지만 그렇지 않은 많은 코드가 포함되어 있다면 간단하지 않을 수 있습니다. 나는 또한 JTest와 함께 일했을 때부터 이것을 측정하려고 시도한 것을 기억하지만,이 경우에는 종종 그것에 동의하지 않았으므로 YMMV를 기억합니다.

  • 시스템의 다른 부분들 사이의 계층 수를 측정하려고 시도 할 수 있습니다. 예를 들어, 데이터베이스에 저장되기 전에 웹 양식에서 가져온 데이터를 몇 개의 다른 코드 조각으로 만날 수 있습니까? 이것은 제대로 측정하기 까다로운 것일 수 있습니다 ...


2
# 3을 블록 깊이라고합니다. 의사 결정 제어 구조가 관련된 경우 Cyclomatic Complexity 와도 관련이 있습니다.
토마스 오웬스

공감 비 설명이 없습니까?
FrustratedWithFormsDesigner

"단순한 언어 기능"에 동의 할 수 없습니다. 코드 를 단순화 하기 위한 고급 기능이 있습니다 . 간단한 기본 기능 만 사용하면 코드가 실제로 수행하는 작업이 모호 해져서 추상화 계층이 유출 될 수밖에 없습니다. 고급 언어 기능을 사용하면 더 높은 수준의 추상화를 표현할 수 있으므로 코드를 훨씬 더 조밀하고 읽을 수 있습니다. 사용하는 고급 기능 (현명하게도)이 단순할수록 좋습니다. 기본 기능만으로 만들어진 유사한 포트란 코드와 Matlab (실제로는 "고급")의 코드를 비교하면됩니다.
SK-logic

그리고 나는 많은 레이어 메트릭에 동의하지 않을 것입니다. 십여 개의 사소하고 깨끗한 단계 또는 하나의 꼬인 변형으로 무언가를 할 수 있다면 여러 단계로 더 잘하십시오. 단순하고 명확하게 분리 된 많은 레이어가 단일 꼬인 레이어보다 훨씬 우수합니다.
SK-logic

@ SK-logic : 나는 그 "영리함"이라고 불렀어야한다고 생각합니다. 나는 ?:그들이 5 깊숙이 중첩되어있을 때 같은 것이 문제 라고 말하고 싶습니다 . 레이어는 깨끗하게 분리 된 레이어가 하나의 복잡한 레이어보다 낫습니다. 그러나 2 개 또는 3 개만 필요할 때 주로 중복되는 7 개의 레이어가 나쁜 것입니다.
FrustratedWithFormsDesigner
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.