티스토리 뷰

반응형


| 4. 주석


--

"나쁜 코드에 주석을 달지 마라. 새로 짜라." 

Brian Wilson Kernighan, Phillip James Plauger


* 주석이 코드에서 분리어 점점 더 부정확한 고아로 변하는 사례가 너무도 흔하다.

* 코드를 깔끔하게 정리하고 표현력을 강화하는 방향으로, 애초에 주석이 필요 없는 방향으로 에너지를 쏟는 편이 좋다.

* 부정확한 주석은 아예 없는 주석보다 훨씬 더 나쁘다.



|| 코드로 의도를 표현하라!


 

> 주석으로 의도를 표현

1
2
3
// 직원에게 복지 혜택을 받을 자격기 있는지 검사
if ((employee.flags & HOURLY_FLAG) &&
    (Employee.age > 65))
cs


> 코드로 의도를 표현

1
if (employee.isEligibleForFullBenefits())
cs



|| 좋은 주석


-

- 어쩔 수 없이 필요한 주석(?)

- 정말로 좋은 주석은 주석을 달지 않을 방법을 찾아낸 주석!


> 법적인 주석

- 저작권 정보와 소유권 정보

1
// Copyright (C) 2021 by Cristoval, Inc. All rights reserved.
cs


> 정보를 제공하는 주석

1
2
3
// kk:mm:ss EEE, MMM dd, yyyy
Pattern timeMatcher = Patter.compile(
    "\\d*:\\d*:\\d* \\w*, \\w*, \\w*, \\d*");
cs


> 의도를 설명하는 주석


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

- 인수나 반환값이 표준 라이브러리나 변경하지 못하는 코드에 속할 경우

1
2
assertTrue(a.compareTo(b) == -1);    // a < b
assertTrue(b.compareTo(a) == 1);    // b > a
cs


> 결과를 경고하는 주석

1
2
3
4
5
6
7
public static SimpleDateFormat makeStandardHttpDateFormat() {
    // SimpleDateFormat은 스레드에 안전하지 못하다.
    // 따라서 각 인스턴스를 독립적으로 생성해야 한다.
    SimpleDateFormat df = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z");
    df.setTimeZone(TimeZone.getTimeZone("GMT"));
    return df;
}
cs


> TODO 주석

- '앞으로 할 일'을 //TODO 주석으로 남겨두기

- 프로그래머가 필요하다 여기지만 당장 구현하기 어려운 업무를 기술

- TODO 주석이 난무한 코드는 바람직하지 않으니 주기적으로 TODO 주석을 점검해 없애는 방법도 필요

1
2
3
4
5
// TODO-MdM 현재 필요하지 않다.
// 체크아웃 모델을 도입하면 함수가 필요 없다.
protected VersionInfo makeVersion() throws Exception {
    return null;
}
cs


> 중요성을 강조하는 주석

- 대수롭지 않다고 여겨질 뭔가의 중요성을 강조하기 위해 주석을 사용

1
2
3
4
5
String listItemContent = match.group(3).trim();
// 여기서 trim은 정말 중요하다. trim 함수는 문자열에서 시작 공백을 제거한다.
// 문자열에 시작 공백이 있으면 다른 문자열로 인식되기 떄문이다.
new ListItemWidget(this, listItemContent, this.level + 1);
return buildList(text.substring(match.end()));
cs



|| 나쁜 주석


-

- 주석을 달기로 결정했다면 충분한 시간을 들여 최고의 주석을 달도록 노력하라.

1. 이해가 어렵게 주절거리는 주석

2. 코드와 같은 이야기를 중복하는 주석

3. 오해의 여지가 있는 주석

4. 의무적으로 다는 주석 (javadocs ..)

5. 이력을 기록하는 주석

6. 있으나 마나 한 주석

7. 무서운 잡음

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

9. 위치를 표시하는 주석

10. 닫는 괄호에 다는 주석

11. 주석으로 처리한 코드

12. HTML 주석

13. 모호관 관계의 설명



||| 주석을 잘 활용한 코드


--

(https://github.com/ludwiggj/CleanCode/blob/master/src/clean/code/chapter04/PrimeGenerator.java)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/**
 * 이 클래스는 사용자가 지정한 최대 값까지 소수를 구한다.
 * 알고리즘은 에라스토테네스의 체다.
 * 2에서 시작하는 정수 배열을 대상으로 작업한다.
 * 처음으로 남아 있는 정수를 찾아 배수를 모두 제거한다.
 * 배열에 더 이상 배수가 없을 때까지 반복한다.
 * 
 */
 
public class PrimeGenerator {
  private static boolean[] crossedOut;
  private static int[] result;
 
  public static int[] generatePrimes(int maxValue) {
    if (maxValue < 2)
      return new int[0];
    else {
      uncrossIntegersUpTo(maxValue);
      crossOutMultiples();
      putUncrossedIntegersIntoResult();
      return result;
    }
  }
 
  private static void uncrossIntegersUpTo(int maxValue) {
    crossedOut = new boolean[maxValue + 1];
    for (int i = 2; i < crossedOut.length; i++)
      crossedOut[i] = false;
  }
 
  private static void crossOutMultiples() {
    int limit = determineIterationLimit();
    for (int i = 2; i <= limit; i++)
      if (notCrossed(i))
        crossOutMultiplesOf(i);
  }
 
  private static int determineIterationLimit() {
    // 배열에 있는 모든 배수는 배열 크기의 제곱근보다 작은 소수의 인수다.
    // 따라서 이 제곱근보다 더 큰 수자의 배수는 제거할 필요가 없다.
    double iterationLimit = Math.sqrt(crossedOut.length);
    return (int) iterationLimit;
  }
 
  private static void crossOutMultiplesOf(int i) {
    for (int multiple = 2 * i;
         multiple < crossedOut.length;
         multiple += i)
      crossedOut[multiple] = true;
  }
 
  private static boolean notCrossed(int i) {
    return crossedOut[i] == false;
  }
 
  private static void putUncrossedIntegersIntoResult() {
    result = new int[numberOfUncrossedIntegers()];
    for (int j = 0, i = 2; i < crossedOut.length; i++)
      if (notCrossed(i))
        result[j++= i;
  }
 
  private static int numberOfUncrossedIntegers() {
    int count = 0;
    for (int i = 2; i < crossedOut.length; i++)
      if (notCrossed(i))
        count++;
 
    return count;
  }
 
  public static void main(String[] args) {
    for (int i : generatePrimes(50)) {
      System.out.print(i + " ");
    }
  }
}
 
cs



출처 : 클린 코드 (Robert C. Martin)

반응형
댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday