본문 바로가기
Programming/C와 C++ 게임 코드로 알아보는 코딩의 기술(저자 오즈 모리하루)

03. 소스 코드 품질 측정

by minjunkim.dev 2020. 8. 22.

    모든 내용은 [오즈 모리하루 저, "C와 C++ 게임 코드로 알아보는 코딩의 기술", 한빛미디어] 를 기반으로 제 나름대로 이해하여 정리한 것입니다. 다소 부정확한 내용이 있을수도 있으니 이를 유념하고 봐주세요!


# 매트릭스 측정

- 소스 코드의 품질을 정량화할 수 있다.

- 코드의 유지성 또는 가독성을 일정한 기준에 따라 수치로 평가할 수 있다.


1. 파일 또는 함수 단위 매트릭스

1) 코드줄 수 - 적을수록 좋음

2) 주석줄 수 - 적을수록 유지보수가 어려울 것으로 예상

3) 문장줄 수 - 적을수록 좋음

* 문장(statement) : 프로그램 하나의 작동을 나타내는 단위

4) 최대중첩 수 - 적을수록 가독성이 좋음

5) 사이크로매틱 복잡도 : 제어 흐름의 복잡성을 수치화, 제어문 수가 많을수록 수치가 커짐.

- 제어문(if 조건문, for 반복문 등) 개수 + 1

- &&, || 등의 연산자 수도 더함

- switch 조건문의 경우, switch 전체를 1개로 보거나,

case 개수를 모두 복잡더에 더하는 두가지 방법이 존재

- 복잡도가 낮을수록 코드가 단순한 것

- 함수 단위의 사이크로매틱 복잡도가 5 - 10이 넘지 않는 것을 목표로 하자.

6) Halstead 복잡도 : 코드 내부에서 사용되는 연산자와 피연산자의 수로 코드의 복잡도를 구함

- 코드 내부의 어휘 수를 바탕으로 복잡도를 구하는 방법

- 한번에 많은 변수를 다루거나, 복잡하고 긴 계산식을 사용하면 수치가 커짐

- 클래스 또는 함수를 작게 분할하면 Halstead 복잡도도 작아진다.

 

N1 : 연산자 수

N2 : 피연산자 수

n1 : 연산자 종류

n2 : 피연산자 종류

N = N1 + N2 : 프로그램의 길이

n = n1 + n2 : 프로그램의 어휘 수

* Halstaed 복잡도 = N * log2(n)

 

7) 보수성 지표(MI, Maintainability Index)

- 코드의 줄 수, 사이크로매틱 복잡도, Halstead 복잡도 라는 3개의 요소를 이용해

코드의 보수성을 수치화한 것

- 수치가 높을수록 보수성이 좋다는 의미

 

H : Halstead 복잡도
C : 사이크로매틱 복잡도
LOC : 코드줄 수
(CM : 주석비율)

MI = 171 - 5.2*ln(H) - 0.23*C - 16.2*ln(LOC) + 50*sin(sqrt(2.4*CM))


2. 객체 지향 매트릭스 : 응집도와 결합도

- 이들을 측정해 수치화하여 사용하면, 클래스 설계의 좋고 나쁜 정도를 판단이 가능하다.

1) 응집도(LCOM) : 클래스가 하나의 역할에 얼마나 집중하는지를 나타내는 척도

- 클래스의 멤버변수를 몇개의 멤버함수에서 참조하는지를 바탕으로 응집도를 계산

 

a : 클래스의 멤버변수 개수
m : 클래스의 멤버함수 개수
mA : 특정멤버변수에 접근하는 멤버함수의 수
sum(mA) : 각 멤버변수에 대한 mA의 합계

LCOM = {m - sum(mA) / a} / (m - 1)

- 응집도가 높을수록 0에 가까워짐(0에 가까울수록 좋음)

- 응집도가 0.5보다 높으면 책임이 많다고 판단할 수 있음 => 클래스 분할 검토

 

2) (클래스) 결합도(CBO) : 관련 있는 외부클래스의 개수

- 멤버변수, 함수의 매개변수, 상속관계 등에서 외부클래스와 관련있는 부분을 조사한 수

- 낮을수록 좋음

* 상속의 깊이와 자식클래스 수

1) 상속의 깊이(DIT) : 자식클래스 입장에서 자신이 상속을 얼마나 받았는지

2) 자식클래스 수(NOC) : 부모클래스 입장에서 자신의 자식클래스가 얼마나 있는지

- 작을수록 클래스는 변경의 영향이 작으므로 좋다.

- 가능하면 상속보다는 이양을 우선하는 설계가 좋다.

 

3) 클래스의 메서드 수(WMC) : 클래스의 멤버함수 수를 의미함

1) 간단하게 멤버함수의 수를 모두 더하거나

2) 사이크로매틱 복잡도 또는 문장 수를 바탕으로 가중치를 구해 더해서 구함

- 멤버함수가 많을수록 복잡한 클래스라고 말할 수 있다.


3. 코드 클론(코드의 중복) 검출

- 코드 클론이란 코드의 중복을 의미

- 코드 중복은 보수성을 현저하게 낮추는 원인이 됨

- 코드 클론 검출 툴을 사용하면 중복된 코드 블록을 검출할 수 있음

- 코드를 작성할 때 의미없이 복사해서 붙여넣는 것을 피해야 한다.

- 하나의 기능 변경을 위해 여러부분을 수정해야하는 구조를 피하자.


4. 정적 코드 분석

- 소스 코드를 해석해서 오류를 자동으로 검출하는 기술

- 버퍼 오버플로 또는 메모리릭 등의 오류를 자동으로 검출해줌

- 치명적인 오류 이외에도 초기화되지 않은 변수, 항상 결과가 같은 조건식 등의 단순 실수도 발견함

- 프로그램을 실행하지 않고 정적으로 해석하므로,

개발 도중에도 컴파일만 가능한 상태라면 언제든지 오류를 검출할 수 있음

- 정적 분석 툴을 활용하면 코드의 품질을 높일 수 있으나,

코드의 가독성이 올라가는 것은 아님


5. 매트릭스 활용 방법

- 매트릭스 측정 결과를 코딩 규약으로 활용하자.

1) 사이크로매틱 복잡도, 제어문 중첩수, 문장수 등에 대해

"목표, 기준, 한계를 설정"하고 이를 통해 코드 리뷰 대상을 설정한다.
2) 측정결과를 우선순위로 코드 리뷰 대상을 결정하고 진행하면 비교적 효율적이다.
3) 그러나, 매트릭스 측정을 목적으로는 하지 말자.
(이미 가독성이 높고, 중복이 없다면 무리하게 수치를 맞추려고 불필요하게 계속 수정하지 말자.)
4) 매트릭스 측정으로 개발자 평가하지 말자.


6. 마치며

- 매트릭스 측정의 추천 사용방법은 "나쁜 부분을 확실하게 찾기"

- 이런 함수나 클래스들을 찾아 개선하는 것만으로도 충분한 효과가 있다.
- 바쁜 개발현장에서는 코드 리뷰가 소홀해질 수 있으나,

나쁜 부분을 확실하게 찾아 리뷰하는 것은 충분한 효과가 있다.


* 매트릭스 측정과 정적코드 분석툴 소개
1) SourceMonitor : 무료 매트릭스 측정툴
2) CppCheck : 무료 정적 해석툴


[출처] : 오즈 모리하루 저, "C와 C++ 게임 코드로 알아보는 코딩의 기술", 한빛미디어