비밀 코드는 높은 소프트웨어 품질에 필요한 작성,디버그 및 유지 관리가 복잡한 것입니다. 또한 코드 복잡성이 높으면 코드 결함 수준이 높아져 코드를 유지 관리하는 데 비용이 많이 듭니다.
따라서 코드 복잡성을 줄임으로써 수명 비용과 함께 버그 및 결함의 수를 줄일 수 있습니다. 복잡한 코드는 정확히 무엇입니까? 전체 코드베이스 또는 하나의 작은 함수인지 여부에 관계없이 코드 조각이 얼마나 복잡한 지 객관적으로 어떻게 평가할 수 있습니까?
이 기사에서는 코드 복잡성을 평가하기위한 세 가지 복잡성 메트릭을 살펴 보겠습니다. 이들은:
- 순환 복잡성
- 스위치 문 및 논리 조건 복잡성
- 개발자 기술
또한 코드 복잡성을 평가하고 이해하는 몇 가지 이점을 살펴 보겠습니다.
순환 복잡도
1976 년 토마스 맥케이브는 순환 복잡도라는 코드 복잡성을 계산하는 메트릭을 제안했다. 그것은 다음과 같이 정의됩니다:
프로그램의 소스 코드를 통한 선형 독립 경로의 수를 정량적으로 측정하여 프로그램의 제어 흐름 그래프를 사용하여 계산했습니다.
제어 흐름 그래프에 익숙하지 않은 경우:
실행 중에 프로그램을 통해 통과 할 수있는 모든 경로의 그래프 표기법을 사용하는 표현입니다.
더 솔직하게 말하면 코드 조각을 통한 경로가 적고 경로가 덜 복잡할수록 순환 복잡성이 낮아집니다. 따라서 코드는 덜 복잡합니다. 메트릭을 보여주기 위해 다소 임의적 인 세 가지 코드 예제를 사용하겠습니다.
예제 1
func main() { fmt.Println("1 + 1 =", 1+1)}
함수를 통과하는 경로가 하나 뿐이므로 순환 복잡성 점수는 1 입니다.
예제 2
func main() { year, month, day := time.Now().Date() if month == time.November && day == 10 && year == 2018 { fmt.Println("Happy Go day!") } else { fmt.Println("The current month is", month) }}
이 예제에서는 현재 연도,월 및 일을 검색합니다. 이 정보를 통해 현재 날짜가 2018 년 11 월 10 일인 경우/다른 조건으로 확인됩니다.
이 경우,코드 인쇄”해피 이동 일!”콘솔에. 그렇지 않은 경우”현재 월”과 현재 월의 이름을 인쇄합니다. 코드 예제는 조건이 세 개의 하위 조건으로 구성된 경우와 같이 더욱 복잡해집니다. 그 점을 감안할 때,그것은 4 의 더 높은 복잡성 점수를 가지고 있습니다.
예제 3
func main() { _, month, _ := time.Now().Date() switch month { case time.January: fmt.Println("The current month is January.") case time.February: fmt.Println("The current month is February.") case time.March: fmt.Println("The current month is March.") case time.April: fmt.Println("The current month is April.") case time.May: fmt.Println("The current month is May.") default: fmt.Println("The current month is unknown.") }}
이 예제에서는time.Now().Date()
에 대한 호출에서 검색된month
값을 기준으로 현재 월을 인쇄합니다. 함수를 통과하는 경로는 각각 사례 문에 대해 하나씩,기본값에 대해 하나씩 있습니다.
결과적으로 순환 복잡도는 7 입니다. 우리는 기본과 함께,올해의 모든 달을 차지했던 경우,그러나,그 점수는 열네 될 것입니다.
1 은 함수
+1 의 기본 복잡도입니다.’, ‘&&’ 또는’||’
이 세 가지 예제를 사용하여 코드 복잡성을 계산하는 표준 메트릭을 사용하면 코드 조각이 얼마나 복잡한 지 신속하게 평가할 수 있습니다.
우리는 또한 코드의 복잡한 부분이 서로 비교되는 방법을 볼 수 있습니다. 그러나 순환 복잡성은 그 자체로 충분하지 않습니다.
스위치 문 및 논리 조건 복잡성
코드 복잡성의 다음 평가자는 스위치 문 및 논리 조건 복잡성입니다. 아래의 코드 예제에서,나는 두 번째 이동 예제를 촬영 한 세 개의 중첩 된 조건으로 조건 경우 화합물을 분할;원래 조건의 각각에 대해 하나.
func main() { year, month, day := time.Now().Date() output := fmt.Sprintf("The current month is %s", month) if month == time.November { if day == 13 { if year == 2018 { output = fmt.Sprintf("Happy Go day!") } } } fmt.Println(output)}
이해하기 쉬운(또는 덜 복잡한),원래 또는 이것? 지금 뒤에 오는 3 개의 질문을 고려해서 이것에,건설하자.
- 우리가 위에서 한 것처럼 여러 조건이 있고 각 조건이 매우 복잡하다면 어떻게 될까요?
- 각각의 본문에 있는 조건과 코드가 상당히 복잡하다면 어떻게 해야 할까요?
- 코드가 더 쉽거나 이해하기가 더 어렵습니까?
중첩된 조건의 수가 많고 이러한 조건 내의 복잡성 수준이 높을수록 코드의 복잡성이 높다고 말할 수 있습니다.
소프트웨어 개발자 기술 수준
개발자의 기술 수준은 어떻습니까? 아래의 두 번째 이동 예제의 다 버전을 살펴보십시오.
#include <stdio.h>#include <time.h>#include <string.h>int main(){ time_t t = time(NULL); struct tm tm = *localtime(&t); const char * months = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; if (tm.tm_year == 2018 && strncmp(months, "November", strlen(months)) == 0 && tm.tm_mday == 10) { printf("Happy C Day!.\n"); } else { printf("The current month is %s.\n", months); }}
기술적으로 다른 예제가 수행하는 작업을 수행합니다. 그러나 동일한 결과를 얻으려면 더 많은 코드가 필요합니다. 솔직히 말해서,내가 더 잘 알고 있다면,코드는 이동 예제보다 더 이상 없을 수 있습니다.
그러나 동일한 결과를 얻기 위해 필요한 최소값이라고 가정 해 봅시다. 이 두 가지를 비교하면 씨의 구문에 비해 더 자세한 특성을 감안할 때 이해하기가 더 어렵습니다.
비교적 유사한 순환 복잡성 점수에도 불구하고 이전에 경험이 없다면 당신의 인식은 무엇입니까?
코드가 덜 복잡하다고 생각하십니까? 그래서 이것은 코드 복잡성을 이해하는 또 다른 필수 요소입니다.
소프트웨어 복잡성 측정의 이점
코드 복잡성 측정의 4 가지 핵심 이점과 1 가지 추가 이점이 있습니다.
더 나은 테스트
코드 조각을 통해 얼마나 많은 독립적 인 경로가 있는지 알면 테스트 할 경로가 얼마나 많은지 알 수 있습니다.
저는 100%코드 커버리지를 옹호하지 않습니다. 그러나 저는 항상 실용적이고 가능한 한 높은 수준의 코드 커버리지를 옹호합니다.
따라서 코드 경로가 얼마나 많은지 알면 테스트해야 할 경로가 얼마나 많은지 알 수 있습니다. 따라서 코드가 포함되도록 하기 위해 최소한 필요한 테스트 수를 측정해야 합니다.
위험 감소
옛 속담처럼:
코드를 작성하는 것보다 코드를 읽는 것이 더 어렵습니다.
더 많은 것은인 무엇:
- 코드는 작성된 것보다 훨씬 더 많이 읽 힙니다.
- 훌륭한 소프트웨어 개발자는 자신이 작성한 코드 줄(또는 변경)에 의해 평가되어서는 안되며 유지 관리 한 코드의 품질에 의해 평가되어야합니다.
코드 복잡성을 줄임으로써 결함이 작거나 크거나 약간 당황 스럽거나 파산을 유발할 위험을 줄일 수 있습니다.
비용 절감
잠재적인 결함의 위험이 감소되면 발견 및 제거해야 할 결함이 줄어듭니다. 그 결과,유지 보수 비용도 줄일 수 있습니다.
우리는 모두 아래 차트에 예시 된 바와 같이 소프트웨어 수명에서 다양한 단계에서 결함을 찾는 것과 관련된 비용을 보았고 잘 알고 있습니다.
따라서 코드의 복잡성과 다른 섹션보다 더 복잡한 섹션을 이해하면 복잡성을 줄일 수있는 훨씬 더 나은 위치에 있습니다.
따라서 복잡성을 줄임으로써 결함을 도입 할 가능성을 줄입니다. 그것은 소프트웨어의 삶의 모든 단계로 흘러 들어갑니다.
더 큰 예측 가능성
소프트웨어 복잡성을 줄임으로써 우리는 더 큰 예측 가능성으로 발전 할 수 있습니다. 내가 의미하는 바는 코드 섹션을 완료하는 데 얼마나 오래 걸리는지 자신감을 가지고 더 잘 말할 수 있다는 것입니다. 이를 알면 출시가 배송되는 데 걸리는 시간을 더 잘 예측할 수 있습니다.
이 지식을 바탕으로 비즈니스 또는 조직은 목표와 기대,특히 상기 소프트웨어에 직접적으로 의존하는 목표를 더 잘 설정할 수 있습니다. 이 경우 현실적인 예산,예측 등을 쉽게 설정할 수 있습니다.
개발자가 학습하는 데 도움
개발자가 학습하고 성장하도록 돕는 것은 코드가 왜 복잡한 것으로 간주되는지를 이해하는 데 최종적인 이점입니다. 이 시점까지 복잡성을 평가하는 데 사용한 도구는 그렇게하지 않습니다.
그들이하는 일은 전체 또는 세분화 된 복잡성 점수를 제공하는 것입니다. 그러나 코드성과 같은 포괄적 인 코드 복잡성 도구가 있습니다.
위의 스크린 샷에서,우리는 나열된 여섯 개 파일 중 하나가(30)의 복잡성,일반적으로 매우 높은 것으로 간주 점수를 가지고 있음을 볼 수 있습니다.
순환 복잡성은 주어진 변경 사항에 대해 코드 품질이 저하되는지 이해하는 훌륭한 지표입니다. 순환 복잡성은 무한 스케일이 주어지고 모듈 크기와 관련이없는 전체 모듈을 보거나 비교할 때 추론하기가 더 어려울 수 있습니다. 그러나 유용 할 수있는 것은 우선 순위별로 정렬 된 코드시의 파일 목록을 보는 것입니다.이 목록은 어떤 파일이 코드 품질이 좋지 않은 후보인지 이해 한 다음 결과적으로 모듈을 이해하는 데 도움이됩니다.
이것은 랩
또한 코드 복잡성이 무엇인지,어떻게 평가되는지,그리고 코드 감소의 중요한 이점에 대한 심층적 인 논의였습니다. 여기서 다룬 것보다 코드 복잡성을 이해하는 데 더 많은 것이 있지만,우리는 그것을 이해하는 데 먼 길을 갔습니다.
이 용어에 대해 처음 듣거나 도구에 대해 배우는 경우 링크 된 기사와 도구를 탐색하여 더 많은 것을 배울 것을 권장합니다. 당신은 이동 또는 씨에서 코딩하지 않는 경우,구글”코드 복잡성 도구”플러스 소프트웨어 언어(들). 당신은 많은 도구를 사용할 수 찾을 확신합니다.
코드 품질을 개선하기위한 더 많은 팁은 코드에서 다른 블로그 게시물을 확인하십시오.
마지막으로,코드 품질을 평가하기위한 포괄적 인 도구와 개발자가 배우고 성장하는 데 도움이되는 도구를 원한다면 코드화를 시도하십시오.
코드시는 수천 명의 개발자가 매일 수십억 줄의 코드를 분석하는 데 사용됩니다!
시작은 쉽고 무료입니다! 당신의 안드로이드 장치에 대한 새로운 게임을 발견하는 큰 물고기 게임 앱 받기!
시작하기