31장: 레이아웃과 스타일
31장: 레이아웃과 스타일
- 레이아웃의 첫 우선순위는 코드의 논리 구조를 시각적으로 드러내는 것임.
- 형식화에는 의견 차이가 많지만, 관례 자체보다 객관적인 기준을 세우고 일관되게 적용하는 일이 중요함.
- 여기서 소개하는 모든 내용에 동의하지 않을지도 모르지만, 핵심은 형식화 스타일에 관련된 사항을 고려하는것
31.1 레이아웃의 기본
- 코드를 보기 좋게 작성하는 것도 중요하나 코드의 구조를 보여주는것이 더 중요
좋은 레이아웃의 목표
- 논리 구조를 정확하게 표현함: 들여쓰기와 공백으로 사람이 보는 구조가 컴퓨터가 해석하는 구조와 같게 만듦.
- 일관되게 적용할 수 있음: 같은 종류의 코드에는 같은 형식을 적용하고, 예외가 필요한 경우에도 명확하고 제한적으로 다룸.
- 가독성을 높임: 컴파일러가 요구하는 최소 공백만 두는 것이 아니라, 코드를 쉽게 읽게 하는 형식을 사용함.
- 수정에 견딤: 한 줄을 수정할 때 여러 줄의 정렬을 함께 고치지 않아도 되는 형식을 선택함.
- 간단한 문장·블록을 구현하는 줄 수를 줄이는 일도 고려 대상일 수 있으나, 위 목표보다 우선하지는 않음.
31.2 레이아웃 기법
공백
- 공백, 탭, 줄바꿈, 빈 줄은 프로그램 구조를 보여 주는 주된 수단임.
- 책의 장·문단·문장 구분처럼 공백은 독자가 코드의 조직을 훑고 중요한 부분을 찾게 함.
- 프로그램은 정보 밀도가 높으므로, 책보다 더 많은 구조 단서를 제공해야 함.
그룹화
- 공백은 관련 있는 문장을 하나의 그룹으로 보이게 하는 수단이기도 함.
- 코드 문단에는 하나의 작업을 수행하며 서로 관련된 문장만 포함함. 관련 없는 문장을 한 묶음에 넣지 않음.
빈 줄
- 관련 문장을 묶는 것만큼 관련 없는 문장을 분리하는 일도 중요함.
- 빈 줄은 코드 문단을 나누고, 루틴을 구분하고, 주석을 강조해 프로그램의 조직을 보임.
- 빈 줄이 지나치게 많으면 디버깅 시간을 늘릴 수 있으므로, 구조를 드러내는 경계에 사용함.
들여쓰기
- 들여쓰기는 논리적 종속 관계를 보여 주어야 함. 들여쓰지 않으면 구조가 사라지고, 실제 구조보다 더 깊게 보이게 하면 복잡성을 과장함.
- 연구 결과는 2~4칸 들여쓰기가 읽기에 적절하다고 봄. 6칸처럼 넓은 들여쓰기는 미적으로는 좋아 보여도 이해를 방해할 수 있음.
괄호
- 두 항보다 복잡한 식은 평가 순서를 기억해야 하지 않도록 괄호를 넉넉히 사용함.
31.3 레이아웃 스타일
블록을 배치하는 방식에는 순수 블록, 중괄호로 순수 블록을 흉내 내는 방식, 중괄호를 블록 경계로 보는 방식, 줄 끝 정렬 방식이 있음.
- 순수 블록은 제어문의 시작과 끝이 자연스럽게 대응하는 언어에서 사용함. Java의 관례적 스타일도 이에 가까움.
- C++에서는 중괄호를 제어문의 일부처럼 두는 방식과 블록 경계로 두는 방식이 모두 가능하며, 이해도 차이는 뚜렷하지 않음.
- 줄 끝 정렬은 조건식이나 이름의 길이가 바뀌면 관련 줄을 함께 옮겨야 하므로 유지보수에 약하고, 복잡한 조건에서는 구조를 왜곡함.
- 한 스타일을 선택했다면 예외를 최소화해 일관되게 적용함. 불일치한 형식은 독자를 오도할 수 있음.
31.4 제어 구조 배치
- 제어 구조의 레이아웃은 미관보다 가독성과 이해 가능성에 직접 영향을 주므로 우선순위가 높음.
제어 구조 블록 형식화의 세부 사항
- 들여쓰지 않은
begin-end쌍을 피함 begin-end쌍을 이중으로 들여쓰지 않음
기타 고려 사항
- 문단 사이를 빈 줄로 구분함
- 단일 문장 블록을 일관되게 형식화함
- 복잡한 식의 조건을 줄마다 나눔
goto를 피함goto는 피함. 꼭 필요하면goto문장과 레이블을 각각 독립된 줄에 두고, 레이블은 왼쪽 여백과 빈 줄로 눈에 띄게 표시함.- 레이블 이름은 대문자처럼 눈에 띄는 규칙을 사용해, 비구조적 흐름이 있다는 사실을 숨기지 않음.
case문에 줄 끝 정렬 예외를 두지 않음
예: case의 본문을 사례 이름 길이가 아닌 표준 들여쓰기 폭으로 배치함.
switch ( ballColor ) {
case BallColor_Blue:
Rollout();
break;
case BallColor_WhiteAndBlue:
if ( mainColor == BallColor_White ) {
KnockCoverOff();
}
break;
}
31.5 개별 문장 배치
문장 길이
- 80자 제한은 긴 줄과 깊은 중첩을 경계하게 했지만, 현대 환경에서는 가독성을 해치며 기계적으로 줄을 나눌 이유가 없음. 90자 한 줄이 억지로 나눈 두 줄보다 읽기 쉬울 수 있음.
명확성을 위한 공백
- 논리식의 식별자·연산자 주변에는 공백을 두어 토큰과 연산 구조를 쉽게 읽게 함.
- 배열 참조의 각 인덱스에도 공백을 사용해 중첩된 참조를 구분함.
- 루틴 인수는 쉼표 뒤 공백으로 분리해, 선언과 호출을 대조할 때 각 인수의 위치를 찾기 쉽게 함.
연속 줄 형식화
- 문장이 미완성임을 분명하게 만들것
- 밀접하게 관련된 요소를 함께 둘것
- 루틴 호출의 연속 줄을 표준 들여쓰기 폭만큼 들여쓸것
- 연속 줄의 끝을 쉽게 찾을 수 있게 할것
- 제어문의 연속 줄을 표준 들여쓰기 폭만큼 들여쓸것
- 대입문의 오른쪽을 정렬하지 않음
- 대입문의 연속 줄을 표준 들여쓰기 폭만큼 들여쓸것
한 줄에 한 문장만 사용
- 한 줄에는 문장 하나만 둠. 디버거에서 실행 단위를 구분하고, 수정·검색·주석 배치를 쉽게 만듦.
- 하나의 문장에는 예측하기 어려운 부작용을 하나 이상 넣지 않음. 같은 변수를 증가시키면서 다른 인수로도 사용하는 식은 평가 순서를 혼동하게 함.
- 여러 문장을 한 줄에 쓰면 코드의 실제 복잡성을 숨기고, 줄 번호 기반 오류 확인·디버깅·편집을 어렵게 함.
- 성능 향상도 여러 연산을 한 줄에 둘 근거가 아님. 측정하기 전에는 명확성과 정확성을 우선함.
데이터 선언 배치
- 한 줄에 데이터 선언 하나만 사용함
- 변수를 처음 사용하는 위치 가까이에서 선언함
- 선언을 의미 있는 순서로 배치함
- C++ 포인터 선언에서는 별표를 변수 이름 옆에 두거나 포인터 타입을 선언함
31.6 주석 배치
- 주석은 설명하는 코드와 같은 깊이로 들여써 시각적 구조를 방해하지 않게 함.
- 적어도 빈 줄 하나를 입력하고 주석을 시작할것
31.7 루틴 배치
- 빈줄을 사용해 루틴의 각 부분을 구분할것
- 루틴 인자에 대해서 표준 들여쓰기를 사용할것
31.8 클래스 배치
클래스 인터페이스 배치
- 클래스와 전체 사용법을 설명하는 머리말 주석
- 생성자와 소멸자
- 공개 루틴
- 보호 루틴
- 비공개 루틴과 멤버 데이터
클래스 구현 배치
- 클래스가 들어 있는 파일의 내용을 설명하는 머리말 주석
- 클래스 데이터
- 공개 루틴
- 보호 루틴
- 비공개 루틴
- 한 파일에 클래스가 여러 개라면 각 클래스를 명확하게 식별함
- 클래스 내부의 주석을 지나치게 강조하지 않음
파일과 프로그램 배치
- 한 파일에 클래스 하나만 둠
- 파일 이름을 클래스 이름과 관련되게 지음
- 파일 안의 루틴을 명확하게 구분함
- 루틴을 알파벳순으로 배치함
- C++에서는 소스 파일의 순서를 신중하게 정함
체크리스트: 레이아웃
일반
- 형식화의 주목적이 코드의 논리 구조를 드러내는 것인가?
- 형식을 일관되게 적용할 수 있고, 유지보수하기 쉬우며, 가독성을 높이는가?
제어 구조와 문장
- 이중 들여쓰기를 피하고, 순차 블록을 빈 줄로 구분했는가?
- 복잡한 식과 단일 문장 블록,
case,goto를 일관되고 읽기 쉽게 배치했는가?- 공백으로 논리식·배열 참조·루틴 인수를 읽기 쉽게 만들고, 미완성 문장은 이어짐이 명확한 위치에서 줄바꿈했는가?
주석·루틴·클래스
- 주석이 해당 코드와 같은 수준으로 들여쓰기 되어 있고, 루틴의 각 부분과 루틴 사이가 빈 줄로 구분되는가?
- 클래스와 파일의 관계, 여러 클래스와 루틴의 경계, 루틴 순서가 탐색을 돕는가?
참고 자료
- 브라이언 커니핸·롭 파이크, The Practice of Programming (Addison-Wesley, 1999): C·C++ 중심의 프로그래밍 스타일을 다룸.
- 앨런 버뮬런 외, The Elements of Java Style (Cambridge University Press, 2000); 트레버 미스펠트 외, The Elements of C++ Style (Cambridge University Press, 2004).
- 브라이언 커니핸·P. J. 플라우거, The Elements of Programming Style, 2판 (McGraw-Hill, 1978): 프로그래밍 스타일을 다룬 고전임.
- 도널드 커누스, Literate Programming (Cambridge University Press, 2001): 프로그래밍 언어와 문서 언어를 결합하는 접근을 제시함.
요점 정리
- 레이아웃은 정확성, 일관성, 가독성, 유지보수성을 기준으로 코드의 논리 구조를 드러내야 하며, 미관은 그 다음이다.
- Visual Basic에서는 순수 블록을, Java에서는 관례적인 순수 블록을 사용한다. C++에서는 순수 블록 모방과 중괄호 경계 방식이 모두 적절하다.
- 특정 관례보다 그것을 일관되게 적용하는 일이 더 중요하며, 불일치는 가독성을 해칠 수 있다.
- 스타일 논쟁에서는 주관적 미감과 객관적 기준을 구분하고, 명시적인 판단 기준으로 논의해야 한다.