《코드 깔끔의 길》 독서노트(셋째)의 주석을 잘 쓰는 것이 매우 중요하다.

8909 단어
나쁜 코드에 주석을 달지 말고 다시 써라.
프로그래밍 언어가 충분히 표현력이 있거나, 우리가 이런 언어로 의도를 표현하는 데 뛰어나면, 주석이 필요하지 않을 수도 있다. 아마도 전혀 필요하지 않을 것이다.
주석의 적절한 사용법은 우리가 코드로 의도를 표현할 때 겪은 실패를 보완하는 것이다.만약 당신이 주석을 써야 한다는 것을 발견한다면 코드를 통해 표현할 방법이 있는지 다시 생각해 보세요.
본고는 주석을 너무 많이 쓰는 것을 제창하지 않으니 코드로 표현할 수 있으면 주석을 쓰지 마라.

1. 주석은 나쁜 코드를 미화할 수 없다


주석을 쓰는 흔한 동기 중 하나는 엉터리 코드의 존재이다.
소량의 주석이 달린 깔끔하고 표현력 있는 코드는 대량의 주석이 달린 자질구레하고 복잡한 코드보다 훨씬 낫다.엉망진창인 코드를 설명하는 주석을 작성하는 데 시간을 들이기보다는 엉망진창인 코드를 청소하는 데 시간을 들이는 것이 낫다.

2. 코드로 설명


때때로 코드 자체가 그 행위를 설명하기에 충분하지 않다.다행히도, 우리는 코드를 써서 자신의 행동을 설명할 수 있는 경우가 많다.

// Check to see if the employee is eligible for full benefits
if ((employee.flags & HOURLY_DAY) && 
    (employee.age > 65))

이렇게 바꾸는 게 어때요?
if (employee.isEligibleForFullBenefits())


3. 좋은 주석


어떤 주석들은 필수적이고 유리하다.그러나 유일하게 진정한 좋은 주석은 네가 쓰지 않으려고 하는 주석이라는 것을 명심해라.

3.1 법률 정보


버전 및 저작권 성명은 모든 원본 파일의 시작 주석에 놓을 이유가 있는 내용이다

3.2 정보를 제공하는 주석

// format matched kk:mm:ss EEE, MMM dd, yyyy
Pattern timeMatcher = Pattern.compile("\\d*:\\d*:\\d* \\w*, \\w* \\d*, \\d*");

이 정규 표현식은 SimpleDateFormat를 통해 일치하는 것을 의미합니다.format 함수는 특정 형식 문자열의 포맷 시간과 날짜를 사용합니다.
이런 주석은 때때로 유용하지만, 더욱 좋은 방법은 함수 명칭을 이용하여 정보를 표현하는 것이다.

3.3 의도에 대한 해석


때때로 주석은 실현에 관한 유용한 정보를 제공할 뿐만 아니라 어떤 결정 뒤의 의도도 제공한다.
아래의 예에서, 당신은 프로그래머가 이 문제에 제공한 해결 방법에 동의하지 않을지도 모르지만, 적어도 당신은 그가 무엇을 하려는지 알고 있다.
public void testConcurrentAddWidgets() throws Exception {
    WidgetBuilder widgetBuilder = 
        new WidgetBuilder(new Class[] {BoldWidget.class});
    String text = "'''bold text'";
    ParentWidget parent = 
        new BoldWidget(new MockWidgetRoot(), text);
    
    AtomicBoolean failFlag = new AtomicBoolean();
    failFlag.set(false);
    
    // This is our best attempt to get a race condition 
    // by creating large number of threads
    for (itn  i = 0; i < 25000; i++) {
        WidgetBuilderThread widgetBuilderThread = 
            new WidgetBuilderThread(widgetBuilder, text, parent, failFlag);
        new Thread(widgetBuilderThread).start();
    }

    assertEquals(false, failFlag.get());
}


3.4 설명


때때로 매개 변수나 반환값이 난해할 때 주석으로 그 의미를 설명하는 데 도움을 주면 도움이 된다.그러나 전제는 더 좋은 방법이 있는지 생각하고 조심스럽게 주석을 달아야 한다는 것이다.

3.5 경고


때때로 다른 프로그래머에게 어떤 결과가 나타날 수 있음을 경고하는 주석도 유용하다.
public static SimpleDateFormat makeStandardHttpDateFormat() {
    // SimpleDateFormat is not thread safe
    // so we need to create each instance independently.
    SimpleDateFormat df = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z");
    df.setTimeZone(TimeZone.getTimeZone("GMT"));
    return df;
}


위의 예는 아마도 더 좋은 해결 방법이 있을 것이다. 그러나 이 주석은 매우 필요하다.그것은 어떤 절박한 프로그래머가 효율이라는 이름으로 정적 초기기를 사용하는 것을 막을 수 있다.

3.6 TODO 주석


TODO는 프로그래머가 해야 한다고 생각하지만 어떤 이유로 아직 하지 않은 일이다.이것은 불필요한 특성을 삭제하라고 일깨워 주거나, 다른 사람에게 어떤 문제를 주의하라고 요구할 수도 있고, 다른 사람에게 좋은 이름을 지어 달라고 간청할 수도 있다.
현재 대부분의 IDE는 포지셔닝 TODO 주석을 제공하고 정기적으로 이 주석을 보며 더 이상 필요하지 않은 것을 삭제하고 코드를 깔끔하게 한다.

3.7 확대


주석은 어떤 불합리하게 보이는 물건의 중요성을 확대하는 데 쓸 수 있다.
String listItemContent = match.group(3).trim();
// the trim is real important. It removes the starting
// spaces that could cause the item to be recognized 
// as another list
new ListItemWidget(this, listItemContent, this.level + 1);
return buildList(text.substring(match.end()));

3.8 공통 API의 Javadoc


만약 공공 API를 작성하고 있다면, 좋은 Javadoc를 작성해야 합니다.

4. 나쁜 주석


대부분의 주석은 이런 종류에 속한다.일반적으로 나쁜 주석은 나쁜 코드의 지탱이나 핑계, 또는 잘못된 결정에 대한 수정이며, 기본적으로 프로그래머가 스스로 말하는 것과 같다.

4.1 중얼중얼 혼잣말


작가 자신만 의미를 알고 있는 주석을 쓰는 것이 바로 중얼중얼하는 것이다.

4.2 여분의 주석


코드 자체에 비해 더 많은 정보를 제공할 수 없는 것은 쓸데없는 주석이다.예를 들어 코드의 의미를 증명하지 않았고 코드의 의도나 논리를 제시하지 않았다.이런 주석을 읽는 것보다 코드를 읽는 것이 낫다.

4.3 오류 주석


주석이 정확하지 않아 코드 자체가 표현한 의미와 일치하지 않아 프로그래머를 오도하기 쉽다.

4.4 정규 주석


함수마다 Javadoc가 있어야 하거나 변수마다 주석이 있어야 한다는 규칙은 완전히 어리석고 가소롭다.이런 주석은 갑자기 코드를 어지럽히고 온통 허튼소리뿐이어서 사람들로 하여금 헷갈리게 한다.

/**
 * @param title The title of the CD
 * @param author The author of the CD
 * @param tracks The number of tracks on the CD
 * @param durationInMinutes The duration of the CD in minutes
 */
public void addCD(String title, String author, int tracks, int durationInMinutes) {
    CD cd = new CD();
    cd.title = title;
    cd.author = author;
    cd.tracks = tracks;
    cd.duration = durationInMinutes;
    cdList.add(cd);
}


4.5 로그 메모


누군가가 코드를 편집할 때마다 모듈의 시작에 주석을 추가합니다.이런 주석은 매번 수정된 로그를 기록하는 것과 같다.
오래전부터 모듈의 시작점에서 이 기록들을 만들고 유지하는 것은 일리가 있었다.그때, 우리는 아직 원본 코드 제어 시스템을 사용할 수 없었다.이제 이런 지루한 기록은 모듈을 엉망진창으로 만들 뿐이니 모두 삭제해야 한다.

4.6 쓸데없는 말


명백한 일에 대해 쉴 새 없이 지껄여 전혀 새롭지 않다.
/** 
 * Default constructor
 */
protected AnnualDateRule() {
    
}

/** The day of the month. */
private int dayOfMonth;

/**
 * Returns the day of the month
 * @return the day of the month
 */
public int getDayOfMonth() {
    return dayOfMonth;
}

4.7 무서운 잔소리


Javadoc가 헛소리일 수도 있어.다음 Javadoc의 목적은 무엇입니까?답: 없습니다.
/** The name. */
private String name;

/** The version */
private String version;

/** The licenseName */
private String licenseName;

/** The version. */
private String info;

이 주석들을 다시 자세히 읽어라.너 커팅 발견했어? - 붙여넣기 오류?만약 작가가 주석을 쓸 때 모두 신경을 쓰지 않았다면 어떻게 독자가 그 중에서 이익을 얻기를 기대할 수 있겠는가?

4.8 함수나 변수를 사용할 수 있을 때는 주석을 쓰지 마라


다음 코드 개요를 보십시오.
// does the module from the global list  depend on the 
// subsystem we are part of ?
if (smodule.getDependSubsystems().contains(subSysMod.getSubSystem()))

주석이 없는 다음 버전으로 변경할 수 있습니다.
ArrayList moduleDependees = smodule.getDependSubsystems();
String ourSubSystem = subSysMod.getSubSystem();
if (moduleDependees.contains(ourSubSystem))

4.9 위치 표시


때때로 프로그래머는 원본 코드에 특정한 위치를 표시하는 것을 좋아한다.예를 들면 다음과 같습니다.
// Actions //////////////////////////////////////////

특정 함수를 이런 표기 아래에 두는 것은 대부분 무리이다.자질구레한 것들은 삭제해야 한다. 특히 꼬리 부분의 쓸모없는 빗장들은 삭제해야 한다.
이렇게 말하자면, 만약 표지판이 많지 않다면, 분명히 알 수 있을 것이다.가능한 한 이 표지판을 적게 써라.만약 남용한다면 코드는 배경 소음에 가라앉아 무시될 것이다.

4.10 괄호 뒤에 오는 주석


때때로 프로그래머는 괄호 뒤에 특수한 주석을 놓는다. 비록 이것은 깊이 있는 끼워 넣는 구조를 포함하는 긴 함수에 의미가 있을 수 있지만, 단지 우리가 쓰기를 원하는 짧고 봉인된 함수에 혼란을 가져올 뿐이다.만약 당신이 오른쪽 괄호를 표시하고 싶다는 것을 발견한다면, 사실 해야 할 일은 함수를 단축하는 것이다.

4.11 서명에 귀속

/* Added by Rick */

버전 제어 시스템은 누가 언제 무엇을 추가했는지 기억하는 데 매우 뛰어나다.작은 서명으로 코드를 더럽힐 필요는 없다.

4.12 주석된 코드


코드를 직접 주석해 버리는 것은 싫은 방법이다.이렇게 하지 마라!
InputStreamResponse response = new InputStreamResponse();
resonpse.setBody(formatter.getResultStream(), formatter.getByteCount());
// InputStream resultsStream = formatter.getResultStream();
// StreamReader reader = new StreamReader(resultStream);
// response.setContent(reader.read(formatter.getByteCount()));

다른 사람들은 주석된 코드를 감히 삭제하지 못한다.그들은 코드가 여전히 거기에 놓여 있는 데는 틀림없이 그 원인이 있을 뿐만 아니라, 이 코드는 매우 중요하기 때문에 삭제할 수 없다고 생각할 것이다.주석이 떨어진 코드가 한데 쌓여 마치 낡은 병 바닥의 찌꺼기와 같다.
한때 코드를 주석해 버리면 쓸모가 있을 수도 있었다.그러나 우리는 이미 우수한 소스 코드 제어 시스템을 가지고 있다. 이 시스템들은 우리에게 필요 없는 코드를 기억할 수 있다.우리는 더 이상 주석으로 표시할 필요가 없다. 삭제하면 된다. 그것들은 잃어버릴 수 없다.보증합니다.

4.13 HTML 주석


원본에 HTML 주석이 포함되어 있어 보기 싫고 읽기 어렵다.

4.14 비로컬 정보


만약 당신이 반드시 주석을 써야 한다면, 주석이 가장 가까운 코드를 설명했는지 확인하십시오.로컬 주석의 상하문 환경에 시스템 수준의 정보를 포함하지 마십시오.다음 예는 무서운 군더더기 외에 시스템급의 기본 포트 정보도 포함한다.그러나 이 함수는 이른바 기본값을 전혀 제어하지 못했다.만약 그 값이 변경된다면, 이 주석도 따라서 수정될 것이라고 보장할 수 없다.
/**
 * port on which fitnesse would run. Default to 8082
 * @param fitnessePort
 */
public void setFitnessePort(int fitnessPort) {
    this.fitnessePort = fitnessePort;
}


4.15 과도한 정보


주석에 재미있는 역사적 화제나 무관한 세부 묘사를 첨가하지 마라.

4.16 불분명한 연계


주석과 묘사된 코드 간의 관계는 분명히 알 수 있을 것이다.만약 당신이 주석을 쓰는 것이 번거롭지 않다면, 적어도 독자들이 주석과 코드를 보고 주석이 말하는 것을 이해할 수 있도록 해라.
Apache 공용 라이브러리의 이 주석을 예로 들면
/**
 * start with an array that is big enough to hold all the pixels
 * (plus filter bytes), and an extra 200 bytes for header info
 */
this.pngBytes = new byte[((this.width + 1) * this.height * 3) + 200];

필터 바이트가 뭐예요?그것+1과 관계가 있습니까?*3과 관련이 있습니까?아니면 둘 다 관계가 있는 건가요?주석의 역할은 스스로 해석하지 못한 코드를 해석하는 것이다.주석 자체에 해석이 필요하다면 너무 유감이다.

4.17 함수 헤드


단함수는 너무 많은 설명을 필요로 하지 않는다.한 가지 일만 하는 짧은 함수에 좋은 이름을 짓는 것은 보통 함수 헤더의 주석을 쓰는 것보다 낫다.

4.18 비공식 코드의 Javadoc


Javadoc는 공공 API에 매우 유용하지만, 공공 용도로 사용하지 않으려는 코드는 혐오스럽다.시스템의 클래스와 함수를 위한Javadoc 페이지를 만드는 것은 항상 유용한 것이 아니라, Javadoc 주석의 추가 형식 요구는 거의 여덟 개의 문장과 같다.

좋은 웹페이지 즐겨찾기