코드를 읽는 행위에 대해 살펴보자. 연구(Measuring Program Comprehension)에 의하면 프로그래머는 프로그래밍 시간 중 60%를 코드 이해에 사용한다. 따라서 정확도를 유지하면서 코드를 빨리 읽어야 효율이 증가한다.
코드를 신속하게 읽기
코드를 읽을 때 대부분의 프로그래머는 그 코드에 존재하는 특정 정보를 찾는다. 따라서 관련 정보를 신속하게 찾는 능력의 향상은 곧 효율의 향상이다. 다음과 같은 코드가 존재하고 이 코드를 이해해야 한다고 해보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
public class InsertionShort {
public static void main(String[] args) {
int[] array = {2, 4, 1, 10, 20, 14};
int temp;
for (int i = 0; i < array.length; i++) {
for (int j = i; j > 0; j--) {
if (array[j] < array[j - 1]) {
temp = array[j];
array[j] = array[j - 1];
array[j - 1] = temp;
}
}
}
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
}
|
cs |
이 코드를 읽을 때 클래스 이름이 InsertionShort 이므로 삽입 정렬을 구현한 코드라는 것을 알 짐작할 수 있다. 따라서 이 코드를 읽을 때 LTM에 저장된 삽입 정렬에 대한 지식과 STM에 저장된 변수 이름 등을 복합적으로 사용하게 된다. 이제 다음과 같은 코드를 보자
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public void execute(int x[]) {
int b = x.length;
for (int v = b / 2 - 1; v >= 0; v--)
func(x, b, v);
for (int l = b - 1; l > 0; l--) {
int temp = x[0];
x[0] = x[l];
x[l] = temp;
func(x, l, 0);
}
}
|
cs |
이 코드는 메서드 이름이나 변수 이름을 통해 LTM에 저장된 프로그래밍 지식을 이끌어낼 수 없다. 따라서 대부분의 경우 STM에 의존하기 때문에 코드를 일기 위해 더 많은 리소스가 필요하다.
생소한 코드를 읽는 것은 왜 어려운가
STM의 기억력은 30초를 넘지 않고 용량 또한 2~6개 사이로 극히 적다. 이것이 STM에 많이 의존해야 하는, 생소한 코드를 읽기 어려운 이유다.
기억의 크기 제한을 극복하기
위 이론대로 라면 STM을 사용하기 때문에 코드에서 6개 넘는 문자를 기억할 수 없다. 하지만 실상은 더 많은 것을 기억한다. 그 이유는 LTM을 사용해 단위(chunk)로 정보를 묶기 때문이다. 예컨대 위 코드에서 코드 여러 줄을 InsertionShort라는 단위로 묶는 것이다. InsertionShort라는 청크로 위 코드를 묶을 때 LTM에 존재하는 삽입 정렬에 대한 지식을 사용하게 된다. 따라서 LTM에 존재하는 프로그래밍 지식이 많은 전문가가 초보자 보다 더 많은 코드를 기억한다.
읽는 것보다 보는 것이 더 많다
STM에 정보가 도달하기 전에 정보는 감각 기억 공간(Sensory Memory)이라는 영역을 통과한다. 이 영역은 각 감각에 대한 정보를 임시 저장하는 버퍼 같은 역할을 한다. 여러 종류의 감각 기억 공간 중 프로그래밍과 관련된 영상 기억 공간(Iconic Memory)이라는 시각 관련 기억 공간을 살펴보자.
영상 기억 공간
정보가 감각 기관을 통해 들어오면 감각 기억 공간에 임시 저장돼었다가 STM으로 전달된다. 하지만 "The Inoframtion Available in Brief Visual Presentation"에 의하면 감각 기억 공간에 임시 저장된 지식이 모두 STM으로 전달되지 않는다. STM의 저장 공간은 감각 기억 공간의 절반 정도다.
영상 정보와 코드
위에서 언급했 듯 모든 영상 기억 공간에 저장된 정보를 STM으로 이전할 수 없기에 무의식적으로 코드를 읽을 때 처리할 수 있는 부분을 선택한다. 따라서 무의식 적으로 중요한 부분을 놓치기도 한다. 이는 코드에 대해 STM이 처리할 수 있는 것보다 더 많은 정보를 저장하는 것이 이론적으로는 가능하다는 것을 의미한다.
기억하는 대상이 중요한 것이 아니고 기억하는 방식이 중요하다
알골 언어 키워드를 21개 주고 초급, 중급, 고급 프로그래머들에게 이 키워드를 기억하게 하는 실험이 있었다. 이 실험에서 고급 프로그래머들은 키워드들을 이미 가지고 있는 지식을 이용해 묶어 기억했다. 예를 들어 TRUE와 FALSE를 묶고, IF, THEN, ELSE를 묶는 식이다. 이를 통해 일상적이고 예상 가능한 상황은 청크로 묶는 것을 쉽게 한다는 것을 알 수 있다. 따라서 그룹을 나누기 쉬운 코드가 읽기 쉬운 코드라 추측할 수 있고 이에 대한 연구 역시 진행되었다.
디자인 패턴의 사용
그룹을 묶기 쉬운 코드로 작성하기 위해선 디자인 패턴을 사용하면 된다. 현직 개발자를 대상으로 한 실험에서 디자인 패턴을 알고 난 후 이를 사용해 코드를 수정할 때 소요되는 시간이 패턴을 사용하지 않았을 경우 보다 더 적게 소요된다는 결론을 얻었다. 즉, 디자인 패턴이라는 지식을 사용해 여러 정보를 청킹 했다.
주석문 쓰기
연구 결과에 의하면 개발자는 주석문을 포함한 코드를 읽을 때 주석문을 포함하지 않는 코드보다 더 많은 시간을 사용한다. 따라서 주석문을 사용하면 개발자는 주석들을 읽는다는 의미다. 따라서 복잡한 로직을 간단히 서술하는 주석(ex - XXX 알고리즘을 사용한다.)은 개발자가 코드를 읽을 때 청킹을 도와줘서 읽기에 도움이 된다.
표식 (beacon) 남기기
표식은 개발자가 코드를 읽을 때 그 코드가 어떤 역할을 하는지 알려주는 역할을 한다. 표식은 코드를 일고 이해하는 과정에서 소스 코드에 대해 개발자가 갖는 가정의 오류 여부를 확인시켜 주기에 중요한 역할을 한다.
표식에는 단순 표식(simple beacon)과 복합 표식(compound beacon)이 존재한다. 단순 표식은 의미 있는 변수명 같은 코드의 문법을 통해 의미가 저명한 표식이다. 언어 자체에서 지원하는 키워드도 단순 표식에 해당된다. 복합 표식은 여러 단순 표식으로 이루어진 더 큰 단위를 의미한다. 인스턴스의 메서드를 호출할 경우 '인스턴스.메서드(..)'와 같은 모양을 갖는대 이런 것이 복합 표식이다.
표식은 청크와 관련 있지만 대부분의 연구자들은 이 둘을 다른 개념으로 보고 있다. 표식은 보통 청크보다는 작은 코드의 일부분으로 받아들여진다.
청킹 연습
경험이 쌓이면 프로그래밍 지식이 늘어나면서 코드에 대한 청킹 능력이 늘긴 하지만, 코드 청킹을 의도적 연습(deliberate practice - 기술 향상을 위해 조금씩 연습하는 것)을 통해 훈련하는 것도 좋다.
코드 청킹을 연습하는 방법은 다음과 같다
- 50줄이 넘지 않는 코드를 준비한다
- 최대 2분이 넘지 않는 시간 동안 코드를 파악한다
- 종이나 IDE에 파익 했던 코드를 기억해 내면서 작성해 본다
- 원래 코드와 스스로 작성한 코드를 비교하면서 회고한다. 회고 시 다음과 같은 질문을 한다.
- 어느 부분을 쉽게 기억했는가?
- 부분적으로 기억한 코드가 있는가?
- 전체를 다 기억하지 못한 코드가 있는가?
- 기억하지 못한 라인들이 있다면 그 이유가 무엇일까?
- 기억하지 못한 라인에 본인이 익숙하지 않은 프로그래밍 개념이 들어 있지는 않은가?
- 기억하지 못한 라인에 본인이 익숙하지 않은 도메인 지식이 있지는 않은가?
- 같이 연습할 사람이 있다면 서로의 코드를 비교해 본다(생략 가능).
출처 - 프로그래머의 뇌