코드를 이해하였다면 그 다음은 코드에 대해 좀 더 깊이 생각하는 것이다. 코드는 왜/어떻게 작성되었고, 기능은 어디에 추가되어야하며, 어떻게 재설계할 것인가 등을 생각해봐야한다
이 장에서는 코드에 대해 깊이 생각하여 코드 작성자의 아이디어, 생각, 결정을 추론할 수 있는 방법과 코드를 깊은 수준에서 생각할 수 있는 세 가지 방법을 살펴보려고 한다.
먼저 코드 추론에 도움이 되는 프레임워크를 알아보고, 이해의 여러 수준에 대해 살펴보고 좀 더 깊이 이해하는 방법, 자연어로 된 텍스트를 읽을 때 도움이 되는 방법 중 코드를 읽는데도 유용한 몇가지를 알아보자
5.1 ‘변수 역할’ 프레임워크
코드에 대해 추론할 때는 변수가 중심적인 역할을 한다. 변수가 어떤 종류의 정보를 담고 있는지 이해하는 것은 코드를 추론하는데 결정적인 역할을 한다. 따라서 적절한 변수명은 표식으로 사용될 수 있고, 코드를 깊이 이해하는데 도움을 준다.
요르마 사야니에미 교수에 의하면 변수를 이해하기 어려운 이유는 대부분의 프로그래머가 변수를 연관지을 좋을 스키마를 자신들의 LTM에 가지고 있지 않기 때문이다.
- “변수”, “정수”처럼 너무 많은 것을 포함하는 청크를 사용
number_of_customer
같은 너무 구체적인 변수명으로 너무 적은 것을 포함하는 청크를 사용
프로그래머는 중간이 필요한데, 이것이 사야니에미가 변수 역할
이라는 프레임워크를 만드는 동기가 되었다. 샤야니메이에 따르면 변수는 11가지 역할로 구분할 수 있다
- 고정값
- 스테퍼
- 플래그
- 워커
- 최근값 보유자
- 목적값 보유자
- 모집자
- 컨테이너
- 추적자
- 조직자
- 임시
5.2 역할과 패러다임
이렇게 변수의 역할을 나누게 되면, 변수에 대해 논의할 때 사용할 수 있는 새로운 용어를 제공해준다. 같은 팀원들이 이 프레임워크를 알고 있으면, 의사소통하는데도 큰 도움이 된다.
또한 이 프레임워크가 효과적인 또 하나의 이유는 몇 개의 역할이 하나로 묶여서 프로그램의 어떤 한 타임을 특정지을 수 있다는 것이다 ex) 스테퍼와 목적값 보유자를 가지면 검색프로그램이다
이 역할과 관련하여 몇가지 팁이 있다
- 생소한 코드를 프린트하여 적어가며 코드를 읽는 것은 코드 이해에 도움이 되는데, 이때 변수 역할을 적어가며 읽을 수 있다
- 코드를 작성할 때 변수명에 역할명을 포함하는 것도 유용하다. 팀원들이 해당 프레임워크를 알고 있으면 더욱 그렇다. 변수명은 길어지지만 변수의 역할을 파악할때 큰 도움이 된다
헝가리안 표기법
- 시스템 헝가리안 표기법 : 타입을 변수명 앞에 붙이는 방식 (ex :
strName
,lDistance
등). 요즘은 에디터에서 타입을 확인하기 쉽기에 굳이 사용하지 않음 - 앱 헝가리안 표기법 : 의미를 가진 단어를 변수명 앞에 붙이는 방식.
- 가독성 측면에서 도움이 되지만, 시스템 헝가리안 표기법이 더 널리 퍼지고 안티패턴으로 지목되면서 안쓰게 되면서 덩달아 안쓰게 되었다.
5.3 프로그램에 대해 깊이 있는 지식을 얻으려면
변수 역할과 변수에 직접 원을 그려가며 관계를 파악하는 것은 효과적이지만 전체 프로그램에 비해 국지적이다. 프로그램에 대해 더 깊이 이해하는 방법에 대해 알아보자. (코드 작성자의 목적, 의사결정이 어떻게 이뤄졌는지)
텍스트 지식 대 계획 지식
낸시 페닝턴은 프로그래머가 소스 코드를 이해하는 두 개의 서로 다른 층위에 대한 모델을 제시했다
- 텍스트 구조 지식 : 키워드가 하는 일이나 변수의 역할 같은 프로그램의 표면적인 이해
- 계획 지식 : 프로그래머가 프로그램을 작성할 때 계획한 것이 무엇인지 혹은 무엇을 달성하려고 했는지.
- 코드가 어떤 구조로 되어있고, 어떻게 연결되어있는지 살펴볼 때 명확해진다
프로그램 이해의 여러 단계
조너선 실리토는 코드를 이해하는 4가지 단계에 대해 정의하였다. 표면적 지식으로부터 좀 더 깊은 이해로의 진행은 아래 4가지 단계를 거친다
- 초점을 찾는다
- 코드를 읽기 시작하는 지점. (ex : main(), 런타임 오류, 프로파일러 결과 오래걸리는 라인 등)
- 초점으로부터 지식을 확정한다.
- 코드에 존재하는 관계를 찾아봐라.
- 역할이 있는 개체(변수, 메서드, 클래스 등)을 표시하고 슬라이스를 찾아라
- 슬라이스 : 어떤 한 라인 X의 슬라이스는 라인 X와 관련있는 모든 코드라인
- 관련된 개체로부터 개념을 이해한다
- 슬라이스 내 코드의 호출 패턴으로부터 자주 호출하는 메서드는 중요 메서드고, 사용하지 않는 메서드는 일단 무시하라. 코드 구조를 잠깐 바꿔서 스크롤 인지부하를 줄일수도 있다
- 중요부분을 파악했다면 모든 관련 클래스를 나열한다. 이들의 관계에 대해 깊이 생각하자
- 여러 개체에 걸쳐 있는 개념을 이해한다
- 코드에 있는 서로 다른 개념들을 고수준에서 이해한다 (자료구조, 연산의 제약 등)
5.4 텍스트를 읽는 것은 코드를 읽는 것과 유사하다
개발자는 코드를 읽는데 시간을 더 많이 투자한다. 따라서 코드를 읽는 능력을 향상 시켜야하는데, 인간이 텍스트를 읽는 기법 중에서 코드 읽기에도 적용할 수 있다
텍스트를 읽는 것과 코드를 읽는 것
코르비니안 브로드만은 브로드만 영역이라는 두뇌의 서로 다른 52개 영역의 위치를 설명하였다. 각 영역은 단어를 읽거나 기억하는 등 주요 담당하는 정신적 기능이 있다.
야네트 지그문트는 코드를 읽을 때 사용하는 영역은 작업기억공간과 인간언어이해를 담당하는 영역이라고 밝혔다.
샨텔 프랫은 인지 능력과 프로그래밍 사이의 연관성에 관해 연구하였는데, 학생들의 일반적인지능력(작업기억공간 + 추론 능력) > 언어능력 > 산술능력 순으로 프로그래밍 능력에 큰 영향을 끼친다고 밝혔다. 특히 언어능력은 학습률(프로그래밍 관련 학습률)에 가장 크게 영향을 준다고 밝혔다.
우와노 히데타케는 사람들이 코드를 읽을때 먼저 코드를 스캔한다는 것을 발견했다. 이는 자연어로 된 논픽션 텍스트를 읽을때도 흔히 일어나며 코드를 읽을때도 이런 방식이 적용되는 것으로 보인다.
5.5 코드 읽기에 적용해볼 수 있는 텍스트 이해 전략
언어를 이해하는 능력과 코드를 읽는 능력은 크게 연관되어있기에, 텍스트를 이해하는 전략은 코드를 읽을때도 적용할 수 있다. 텍스트 이해 전략은 대략 아래 7가지 범주로 나뉜다
- 활성화 : 관련된 것들을 적극적으로 생각해서 이미 가지고 있는 지식을 활성화하는 것
- 코드를 자세히 읽기 전에 먼저 스캔하는 행위는 코드 내 개념과 문법적 요소들에 대한 일차적인 이해를 하는 효과가 있다.
- 코드의 구성요소에 대해 적극적으로 생각하면 작업 기억 공간이 LTM으로부터 코드를 이해하는 데 도움이 될만한 관련 정보를 찾는 데 도움이 된다.
- 모니터링 : 코드를 읽으며 자신이 이해한 것, 이해하지 못한 것을 관찰하고 표시한다
- 이해되지 않은 부분만 나중에 다시 읽을 수 있지만, 다른 사람에게 설명해달라고 요청할 때도 도움이 된다
- 중요도 결정 : 코드에서 어떤 부분이 중요한지 결정하는 것
- 추론 : 코드에서 명시적으로 주어지지 않은 사실을 유추하는 것.
- 코드의 구조 또는 변수 등 프로그램 구성요소의 이름으로부터 의미를 유추할 수 있다.
- 코드에서 사용된 식별자들을 나열하여 모든 식별자를 파악하여 관련 정보를 LTM에서 검색할 수 있고, 발견된 정보를 통해 작업 기억 공간에서 활용할 수 있다
- 시각화 : 깊이 있는 이해를 위해 텍스트에 대한 도표를 만드는 것
- 상태표, 의존 그래프 (4장), 추가로 연산 테이블 방법이 있다
- 연산 테이블 : 어떤 변수가 어떤 연산에 사용되는지 추적하여 변수가 어떤 타입인지 파악하는 것
- 질문 : 코드에 대해 스스로 질문하는 것 (중심개념, 작성자의 의도, 가정, 효과, 위험요소 등)
- 요약 : 코드를 짧게 요약하는 것
- 자연어로 요약하여도 좋고, 이는 나중에 문서에 포함할 수도 있다