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 클래스 배치

클래스 인터페이스 배치

  1. 클래스와 전체 사용법을 설명하는 머리말 주석
  2. 생성자와 소멸자
  3. 공개 루틴
  4. 보호 루틴
  5. 비공개 루틴과 멤버 데이터

클래스 구현 배치

  1. 클래스가 들어 있는 파일의 내용을 설명하는 머리말 주석
  2. 클래스 데이터
  3. 공개 루틴
  4. 보호 루틴
  5. 비공개 루틴
  • 한 파일에 클래스가 여러 개라면 각 클래스를 명확하게 식별함
  • 클래스 내부의 주석을 지나치게 강조하지 않음

파일과 프로그램 배치

  • 한 파일에 클래스 하나만 둠
  • 파일 이름을 클래스 이름과 관련되게 지음
  • 파일 안의 루틴을 명확하게 구분함
  • 루틴을 알파벳순으로 배치함
  • 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++에서는 순수 블록 모방과 중괄호 경계 방식이 모두 적절하다.
  • 특정 관례보다 그것을 일관되게 적용하는 일이 더 중요하며, 불일치는 가독성을 해칠 수 있다.
  • 스타일 논쟁에서는 주관적 미감과 객관적 기준을 구분하고, 명시적인 판단 기준으로 논의해야 한다.

results matching ""

    No results matching ""