Skip to content

4장 주석

김윤수 edited this page Aug 1, 2022 · 1 revision

나쁜 코드에 주석을 달지 마라. 새로 짜라. -브라이언 W. 커니핸, P.J.플라우거

잘 달린 주석은 어떤 정보보다 유용하다.
다만 프로그래밍 언어를 사용해 의도를 표현할 수 있다면 필요하지 않다.
주석을 사용하지 않고 의도를 표현할 수 없을까? 생각하자.

주석은 나쁜 코드를 보완하지 못한다

주석을 달아야겠다 대신 코드를 정리하자
주석이 많이 달린 코드보다는 주석이 거의 없고 깔끔한 코드가 좋다

코드로 의도를 표현하라!

if ((employee.flags & HOURLY_FLAG) && (employee.age > 65)){}

주석을 사용해야하는 경우는 있다

if (employee.isEligibleForFullBenenfits()){}

하지만 위 코드처럼 대부분 코드로 의도를 표현할 수 있다.

좋은 주석

몇몇 주석은 꼭 필요하다.

법적인 주석

  • 법적인 이유로 소스 파일 첫머리에 들어가는 주석
  • 표준 라이선스나 외부 문서 참조

정보를 제공하는 주석

// kk:mm:ss EEE, MMM dd, yyyy 형식이다.   
pattern timeMatcher = Pattern.compile("\\d*:\\d*:\\d* \\w*, \\w* \\d*, \\d*");
  • 기본적인 정보
  • 다만 클래스를 만들어 코드를 옮기면 주석이 필요 없어짐

의도를 설명하는 주석

  • 구현을 이해를 넘어 결정의 의도 까지 설명
  • 의도를 분명히 드러낼 수 있음

의미를 명료하게 밝히는 주석

   assertTrue(a.compareTo(a) == 0)   // a == a
   assertTrue(a.compareTo(b) != 0)   // a != b
   assertTrue(a.compareTo(ab) == 0)  // ab == ab
  • 모호한 인수나 반환값의 의미를 읽기 좋게 표현
  • 변경하지 못하는 코드의 경우에 유용함 변경 가능하다면 변경
  • 다만 위험할 수 있어 주의하여야 함

결과를 경고하는 주석

  • 결과를 경고하는 목적으로 사용
  • 주석으로 실수를 막을 수 있음
// 여유 시간이 충분하지 않다면 실행하지 마십시오   

TODO 주석

  • 앞으로 할 일 //TODO 주석으로
  • 구현하지 않은 이유와 미래 모습 설명
  • 필요하지만 당장 구현하기 어려운 업무 기술
  • TODO 주석을 많이 사용하는 것은 좋지 않음
// TODO-MdM 현재 필요하지 않다.
// 체크아웃 모델을 도입하면 함수가 필요 없다.

중요성을 강조하는 주석

  • 대수롭지 않다고 여겨질 것의 중요성을 강조하기 위해 사용
// 여기서 trim은 정말 중요하다. trim 함수는 문자열에서 시작 공백을 제거한다.   
// 문자열에 시작 공백이 있으면 다른 문자열로 인식되기 때문이다.  

공개 API에서 Javadocs

  • 공개 API에서 설명하기 위해 사용
  • 공개 API를 구현한다면 Javadocs를 작성하는 것이 좋음

나쁜 주석

대다수의 주석들이 이 범주에 속한다.

  • 허술한 코드를 지탱
  • 엉성한 코드를 변명
  • 미숙한 결정을 합리화
  • 주절거리는 독백

주절거리는 주석

특별한 이유 없이 의무감으로 혹은 프로세스에서 하라고 하니까 다는 주석은 시간낭비이다.

   try
   {
      ...
   }
   catch(IOException e)
   {
      // 속성 파일이 없다면 기본값을 모두 메모리로 읽어 들였다는 의미다.
   }
  • 위 주석은 읽어도 무슨 내용인지 알 수 없음
  • 알아내려면 코드를 분석해야 함
  • 이는 의미 없는 주석임

같은 이야기를 하는 주석

   // this.closed가 true일 때 반환되는 유틸리티 메소드이다.
   // 타임아웃에 도달하면 예외를 던진다.
  • 자칫하면 코드보다 주석을 읽는데 시간이 더 오래 걸림
  • 함수를 대충 읽게하고 넘어가게 하는 주석임
  • 코드를 지저분하고 정신 없게 만듦

오해할 여지가 있는 주석

  • 의도는 좋았으나 오해할 여지가 있음
  • 주석의 잘못된 정보로 인해 골머리를 앓을 수 있음

의무적으로 다는 주석

모든 함수에 Javadocs를 달거나 모든 변수에 주석을 다는것은 어리석다.
이는 코드를 복잡하게 만들고 혼동과 무질서를 초래한다.

/**
 *
 *@param title CD 제목
 ...
 */
public void add(...){
   CD cd = new CD();
   cd.title = title;
   ...
}

무의미한 주석은 잘못된 정보를 제공할 여지만 만든다.

이력을 기록하는 주석

예전에는 모듈 첫머리에 변경 이력을 기록하고 관리하는 관례가 있었다.
당시에는 코드 관리 시스템이 없었다.
지금은 혼란만 가중할 뿐이다.

있으나 마나 한 주석

  • 너무나 당연한 사실을 제공
  • 새로운 정보를 제공하지 못하는 주석
/**
 * 기본 생성자
 */
protected AnnualDateRule() {}
/** 월 중 일자 */
   private int dayOfMonth;

있으나 마나 한 주석 대신 코드를 정리하라.

무서운 잡음

/* The name. */
private String name;

/* The version. */
private String version;

/* The licenceName. */
private String licenceName;
  • 때로는 Javadocs도 잡음임

함수나 변수로 표현할 수 있다면 주석을 달지 마라

  • 주석 대신 함수나 변수로 표현할 수 있다면 하는 것이 좋음

위치를 표시하는 주석

// actions /////////////
  • 때로는 위치를 표시하는것이 유용함
  • 하지만 가독성을 낮추므로 주의하여 사용해야 함

닫는 괄호에 다는 주석

try {
   while() {
   } // while
} // try
  • 중첩이 심하고 복잡한 함수라면 의미가 있을지도 모름
  • 하지만 작고 캡슐화된 함수엔 잡음일 뿐임 주석을 다는 대신 함수를 줄이려 노력하자

공로를 돌리거나 저자를 표시하는 주석

/* 릭이 추가함 */
  • 소스 코드 관리 시스템을 사용한다면 이는 필요없음
  • 시간이 지날수록 부정확하고 쓸모 없어짐

주석으로 처리한 코드

   this.bytePos = writeBytes(pngIdBytes, 0);
   //hdrPos = bytePos;
   writeHeader();
  • 지워도 되는지 의미가 있는 코드인지 알 수 없음
  • 코드 관리 시스템이 기억해줌

HTML 주석

/*
 * </p>
 * <pre>
 * &lt;taskdef;
 ...
 */
  • HTML 주석은 읽기조차 어려움
  • 이는 도구가 책임져야함

전역 정보

  • 주석을 달아야 한다면 근처의 코드만 기술
  • 전반적인 정보를 기술하지 말아야 함

너무 많은 정보

/*
   쓸데 없는 정보
 */
  • 관련 없는 정보를 쓰지 말아야 함

모호한 관계

  • 코드를 설명하는 주석은 명확해야 함
  • 둘의 관계가 모호해서는 안됨

함수 헤더

함수 헤더를 다는 것 보다
이름을 잘 짓는 것이 더 효과적이다.

비공개 코드에서의 Javadocs

공개하지 않는 코드에서의 Javadocs는 불필요하다.