코드 리뷰
개발자가 작성한 코드를 다른 개발자가 정해진 방법을 통해서 검토하는 일
소프트웨어의 품질을 향상, 보장하기 위한 중요한 활동
•
형태
◦
상급자 검토, 집단 검토, 동료 검토,…
•
종류
◦
코드 규칙 검사, 실패 검출, 워크 스루, …
클린 코드
전문가들이 표현한 '클린코드'
1. 한 가지를 제대로 한다.
2. 단순하고 직접적이다.
3. 특정 목적을 달성하는 방법은 하나만 제공한다.
4. 중복 줄이기, 표현력 높이기, 초반부터 간단한 추상화 고려하기 이 세가지가 비결
5. 코드를 읽으면서 짐작했던 기능을 각 루틴이 그대로 수행하는 것
•
의도된 기능을 올바르게 수행한다고 해서 좋은 코드가 만들어진 것은 아님.
•
소프트웨어는 “살아 있는” 개체로 보는 것이 마땅한 듯 ← 요구사항 변화와 코드 변경이 반복되는 것이 일반적
클린코드를 만들기 위한 몇 가지 규칙
1.
네이밍(Naming)
변수, 클래스, 메소드에 의도가 분명한 이름을 사용한다.
잘못된 정보를 전달할 수 있는 이름을 사용하지 않는다.
int elapsedTimeInDays;
int daysSinceCreation;
int fileAgeInDays;
Java
복사
2.
주석달기(Comment)
코드를 읽는 사람이 코드를 작성한 사람만큼 잘 이해할 수 있도록 도와야 한다.
주석은 반드시 달아야 할 이유가 있는 경우에만 작성하도록 한다. 즉, 코드를 빠르게 유추할 수 있는 내용에는 주석을 사용하지 않는 것이 좋다.
설명을 위한 설명은 달지 않는다.
// 주어진 'name'으로 노드를 찾거나 아니면 null을 반환한다.
// 만약 depth <= 0이면 'subtree'만 검색한다.
// 만약 depth == N 이면 N 레벨과 그 아래만 검색한다.
Node* FindNodeInSubtree(Node* subtree, string name, int depth);
Java
복사
3.
꾸미기(Aesthetics)
보기좋게 배치하고 꾸민다. 보기 좋은 코드가 읽기도 좋다.
규칙적인 들여쓰기와 줄바꿈으로 가독성을 향상시키자.
일관성있고 간결한 패턴을 적용해 줄바꿈한다.
메소드를 이용해 불규칙한 중복 코드를 제거한다.
4.
흐름제어 만들기(Making control flow easy to read)
•
왼쪽에는 변수를, 오른쪽에는 상수를 두고 비교
if(length >= 10)
while(bytes_received < bytest_expected)
Java
복사
•
부정이 아닌 긍정을 다루자
if( a == b ) { // a!=b는 부정
// same
} else {
// different
}
Java
복사
•
if/else를 사용하며, 삼항 연산자는 매우 간단한 경우만 사용
•
do/while 루프는 피하자
5.
착한 함수(Function)
함수는 가급적 작게, 한번에 하나의 작업만 수행하도록 작성
온라인 투표로 예를 들어보자.
사용자가 추천을 하거나, 이미 선택한 추천을 변경하기 위해 버튼을 누르면 vote_change(old_vote, new_vote) 함수를 호출한다고 가정
var vote_changed = function (old_vote, new_vote) {
var score = get_score();
if (new_vote !== old_vote) {
if (new_vote == 'Up') {
score += (old_vote === 'Down' ? 2 : 1);
} else if (new_vote == 'Down') {
score -= (old_vote === 'Up' ? 2 : 1);
} else if (new_vote == '') {
score += (old_vote === 'Up' ? -1 : 1);
}
}
set_score(score);
};
JavaScript
복사
총점을 변경해주는 한 가지 역할을 하는 함수같지만, 두가지 일을 하고 있다.
•
old_vote와 new_vote의 상태에 따른 score 계산
•
총점을 계산
별도로 함수로 분리하여 가독성을 향상시키자
var vote_value = function (vote) {
if(vote === 'Up') {
return +1;
}
if(vote === 'Down') {
return -1;
}
return 0;
};
var vote_changed = function (old_vote, new_vote) {
var score = get_score();
score -= vote_value(old_vote); // 이전 값 제거
score += vote_value(new_vote); // 새로운 값 더함
set_score(score);
};
JavaScript
복사
코드의 형태적 명확성
•
문법적 형식
◦
코딩 규약 준수 여부, 올바르고 명확한 문법을 구사하였는지
•
구문 의미적 형식
◦
같은 실행 결과를 낳는 코드 중에서도 생각의 흐름을 더 명확하게 표현하는 코드가 있다.
i = 1; sum = 0
while True:
sum += i
if i == 10:
break
i = i + 1
print("sum = " + str(sum))
Python
복사
코딩 규약,
문법적 합리성 →
i = 1
sum = 0
while i <= 10:
sum += i
i += 1
print("sum = %d" % sum)
Python
복사
의도한 의미를 명확한 표현으로 →
sum = 0
for i in range(1, 11):
sum += i
print("sum = %d" % sum)
Python
복사
짠
코드 인스펙션 (Code Inspection)
제품의 품질을 향상시키기 위해 제품을 실행하지 않고 제품의 소스코드를 확인해 결함을 발견하는 방법.
리뷰와 마찬가지로 코드 인스펙션을 통해 테스트 수행 이전에 결함을 발견할 수 있으며, 동적 테스트로 발견하기 어려운 결함 및 코드의 유지 보수성 등을 향상시킬 수 있어 필수적으로 수행해야 하는 방법이다.
프로젝트 초반에 전문 인력을 투입해 초기에 많은 결함을 발견하고 이를 통해 제품의 품질을 향상 시키는 방법이며, 실제로 많은 성공 사례를 가지고 있는 방법 중 하나이다.
→ 오류 발견 및 수정을 가능한 한 빠른 단계에서 하고자 하는 노력 (비용 절감과 생산성 향상)
절차 과정
1.
Planning : 계획 수립
2.
Overview : 교육과 역할 정의
3.
Preparation : 인스펙션을 위한 인터뷰, 산출물, 도구 준비
4.
Meeting : 검토 회의로 각자 역할을 맡아 임무 수행
5.
Rework : 발견한 결함을 수정하고 재검토 필요한지 여부 결정
6.
Follow-up : 보고된 결함 및 이슈가 수정되었는지 확인하고 시정조치 이행
리팩토링
점진적으로 반복 수행되는 과정을 통해 코드를 조금씩 개선해나가는 것
리팩토링 대상
•
메소드 정리 : 그룹으로 묶을 수 있는 코드, 수식을 메소드로 변경함
•
객체 간의 기능 이동 : 메소드 기능에 따른 위치 변경, 클래스 기능을 명확히 구분
•
데이터 구성 : 캡슐화 기법을 적용해 데이터 접근 관리
•
조건문 단순화 : 조건 논리를 단순하고 명확하게 작성
•
메소드 호출 단순화 : 메소드 이름이나 목적이 맞지 않을 때 변경
•
클래스 및 메소드 일반화 : 동일 기능 메소드가 여러개 있으면 수퍼클래스로 이동
리팩토링 진행 방법
아키텍처 관점 시작 → 디자인 패턴 적용 → 단계적으로 하위 기능에 대한 변경으로 진행