🐱 Meow, meow

유용한 정보가 있는 주석이 있는 반면, 의미가 없거나 JavaDoc 처럼 의무적으로 작성하는 주석이 혼재한다.
어떤 주석을 남겨야 좋은 것인지, 어떤 Convertion 을 가져야 정해야할 지 고민하는 시기가 온다.
Clean Code 관점에서는 어떠한지 찾아보고 정리해보았다.

  • Clean Code
    • Good Comments
      • 법적인 주석 (Legal Comments)
      • 정보를 제공하는 주석 (Informative Comments)
      • 의도를 설명하는 주석 (Explanation of Intent)
      • 설명 (Clarification)
      • 결과를 경고하는 주석 (Warning of Consequences)
      • TODO 주석 (TODO Comments)
      • 강조 (Amplification)
      • 공개 API 에서 Javadocs (Javadocs in Public APIs)
    • Bad Comments
      • 주절거리는 주석 (Mumbling)
      • 중복하는 주석 (Redundant Comments)
      • 오해의 소지가 있는 주석 (Misleading Comments)
      • 의무적인 주석 (Mandated Comments)
      • 이력 기록하는 주석 (Journal Comments)
      • 소음 주석, 있으나 마나 한 주석 (Noise Comments)
      • 무서운 잡음 (Scary Noise)
      • 함수나 변수로 표현할 수 있다면 주석을 달지 마라 (Don’t Use a Comment When You Can Use a Function of a Variable)
      • 위치를 표시하는 주석 (Position Markers)
      • 괄호를 닫는 주석 (Closing Brace Comments)
      • 공로를 돌리거나 저자를 표시하는 주석 (Attributions and Bylines)
      • 주석으로 처리된 코드 (Commented-Out Code)
      • HTML 주석 (HTML Comments)
      • 전역 정보 (Nonlocal Information)
      • 많은 정보 (Too Much Information)
      • 모호한 관계 (Inobvious Connection)
      • 함수 헤더 (Function Headers)
      • 비공개 코드의 Javadoc (Javadoc in Nonpulibc code)
  • Best practices for writing code commentse
    • 규칙 1. 주석은 코드와 중복되어서는 안됩니다.
    • 규칙 2. 좋은 주석은 불분명한 코드를 변명하지 않습니다.
    • 규칙 3. 명확한 주석을 작성할 수 없다면 코드에 문제가 있을 수 있습니다.
    • 규칙 4. 주석은 혼란을 야기하는 것이 아니라 혼란을 해소해야 합니다.
    • 규칙 5. 주석에서 단일 관용어 코드를 설명하세요.
    • 규칙 6. 복사된 코드의 원본 소스에 대한 링크를 제공하세요.
    • 규칙 7. 가장 도움이 될 외부 참조 링크를 포함하세요.
    • 규칙 8. 버그를 수정할 때 주석을 추가하세요.
    • 규칙 9. 불완전한 구현을 표시하려면 주석을 사용하세요.


Clean Code


🍏️ About

로버트 C. 마틴의 Clean Code 의 책 중에서 4장. Comment 에 대한 정리


주석은 잘못된 코드를 보완하지 못한다


코드에 주석을 추가하는 일반적인 이유는 코드 품질이 나쁘기 때문이다.
깔끔하고 주석이 거의 없는 코드가, 복잡하고 어수선하며 주석이 많이 달린 코드보다 훨씬 좋다.
주석으로 설명하려 애쓰는 대신에 그 난장판을 깨끗이 치우는데 시간을 보내라!

“Don’t comment bad code - rewrite it.”
by BrianW.Kernighan and P.J Plaugher


코드로 의도를 표현하라


코드만으로 의도를 표현하기 힘든 경우가 많다.
하지만, 조금만 더 생각해보면 코드로 의도를 표현할 수 있다.

AS-IS TO-BE
// 직원에게 복지 혜택을 받을 자격이 있는지 검사한다.
if ((employee.flags & HOURLY_FLAG) && (employee.age > 65))
                
if (employee.isEligibleForFullBenefits())
                


Good Comments


회사에서 법적인 이유로 저작권과 같이 특정 주석을 작성하도록 강요하는 경우도 있다.

// Copyright (C) 2003,2004,2005 by Object Mentor, Inc. All rights reserved.
// Released under the terms of the GNU General Public License version 2 or later.


2. 정보를 제공하는 주석 (Informative Comments)

주석을 통해 기본 정보를 제공하는 것은 유용하다.

// 테스트 중인 Responder 인스턴스를 반환
protected abstract Responder responderInstance();

🖐 사실 이 경우 주석이 유용할 수 있지만, 함수 이름을 responderBeingTested 로 바꾸면 주석을 쓰지 않을 수 있다.

// kk:mm:ss EEE, MMM dd, yyyy 형식이다.
Pattern timeMatcher = Pattern.compile("\\d*:\\d*\\d* \\w*, \\w*, \\d*, \\d*");

🖐 날짜와 시간의 형식을 바꾸어주는 Utils 과 같은 특별한 클래스로 옮긴다면 주석을 쓰지 않을 수 있다.


3. 의도를 설명하는 주석 (Explanation of Intent)

단순히 구현에 대한 정보를 넘어 숨겨진 의도를 제공한다.

// 스레드를 대량 생성하는 방법으로 어떻게든 경쟁 조건을 만들려 시도한다.
for (int i = 0; i > 2500; i++) {
    WidgetBuilderThread widgetBuilderThread = new WidgetBuilderThread(widgetBuilder, text, parent, failFlag);
    Thread thread = new Thread(widgetBuilderThread);
    thread.start();
}


4. 설명 (Clarification)

라이브러리 부분이거나 변경할 수 없는 코드에는 주석이 유용할 수 있다.

🏷️ 주의

단, 설명이 틀린 경우에는 상당한 위험이 있다.

public void testCompareTo() throws Exception
{
    WikiPagePath a = PathParser.parse("PageA");
    WikiPagePath ab = PathParser.parse("PageA.PageB");
    WikiPagePath b = PathParser.parse("PageB");
    WikiPagePath aa = PathParser.parse("PageA.PageA");
    WikiPagePath bb = PathParser.parse("PageB.PageB");
    WikiPagePath ba = PathParser.parse("PageB.PageA");
    assertTrue(a.compareTo(a) == 0); // a == a
    assertTrue(a.compareTo(b) != 0); // a != b
    assertTrue(ab.compareTo(ab) == 0); // ab == ab
    assertTrue(a.compareTo(b) == -1); // a < b
    assertTrue(aa.compareTo(ab) == -1); // aa < ab
    assertTrue(ba.compareTo(bb) == -1); // ba < bb
    assertTrue(b.compareTo(a) == 1); // b > a
    assertTrue(ab.compareTo(aa) == 1); // ab > aa
    assertTrue(bb.compareTo(ba) == 1); // bb > ba
}


5. 결과를 경고하는 주석 (Warning of Consequences)

특정 결과에 대해 다른 개발자에게 경고하는 주석은 유용하다.
하지만, 문제가 있는 경우에는 해결하는 것이 가장 좋다.

// 여유 시간이 충분하지 않다면 실행하지 마세요.
public void _testWithReallyBigFile() {
    writeLinesToFile(10000000);
    response.setBody(testFile);
    response.readyToSend(this);
    String responseString = output.toString();
    assertSubString("Content-Length: 1000000000", responseString);
    assertTrue(bytesSent > 1000000000);
}

🖐 Junit 의 경우 @Ignore 로 대체할 수 있다.

public static SimpleDateFormat makeStandardHttpDateFormat() {
    // SimpleDateFormat 는 스레드가 안전하지 않습니다.
    // 따라서, 각 인스턴스를 독립적으로 생성해야 합니다.
    SimpleDateFormat df = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z");
    df.setTimeZone(TimeZone.getTimeZone("GMT"));
    return df;
}


6. TODO 주석 (TODO Comments)

해야 할 일을 //TODO 주석 형식으로 남기는 것은 좋다.
TODO 주석은 기능이 왜 퇴보적인 구현을 가지고 있는지, 그 기능의 미래가 어떻게 되어야 하는지 설명해야 한다.
TODO 는 개발자가 해야 한다고 생각한 작업이지만, 어떠한 이유로 지금은 할 수 없고, 사용하지 않는 기능을 삭제 하라는 알림이 될 수도 있다.

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


7. 강조 (Amplification)

중요성을 강조하기 위해 사용 될 수 있다.

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


8. 공개 API 에서 Javadocs (Javadocs in Public APIs)

잘 설명된 공개 API 만큼 도움이 되고 만족스러운 것은 없다.
표준 자바 라이버리를 위한 Javadocs 가 좋은 예이다.


Bad Comments


🏷️ 주의!

대부분의 주석이 이 범주에 속한다.
보통 잘못된 코드에 대한 변명 또는 불충분한 결정에 대한 정당성 같은 내용이다.


1. 주절거리는 주석 (Mumbling)

아래 코드에서 catch 블록에 있는 주석은 저자에게는 의미가 있겠지만, 다른 사람들에게는 의미가 없다.
저 주석의 의미를 알아내려면 다른 코드를 봐야하는데, 이해가 안되어 다른 모듈까지 뒤져야 하는 주석은 제대로 된 주석이 아니다.

public void loadProperties() {
    try {
    String propertiesPath = propertiesLocation + "/" + PROPERTIES_FILE;
    FileInputStream propertiesStream = new FileInputStream(propertiesPath);
    loadedProperties.load(propertiesStream);
    } catch (IOException e) {
    // 속성 파일이 없다면 기본값을 모두 메모리로 읽어 들였다는 의미다.
    }
}


2. 중복하는 주석 (Redundant Comments)

코드 내용을 그대로 중복하는 주석은 전혀 필요 없는 코드이다.

// this.closed가 true일 때 반환되는 유틸리티 메서드다.
// 타임아웃에 도달하면 예외를 던진다.
public synchronized void waitForClose(final long timeoutMillis) throws Exception {
    if (!closed) {
        wait(timeoutMillis);
        if (!closed) {
            throw new Exception("MockResponseSender could not be closed");
        }
    }
}

Tomcat 코드에서 중복된 Javadocs 는 오히려 주석이 어수선하고 코드를 모호하게 만들며, 문서적인 목적에는 전혀 도움이 되지 않는다.

    ...(생략)..
    /**
     * The Logger implementation with which this Container is associated.
     */
    protected Log logger = null;


    /**
     * Associated logger name.
     */
    protected String logName = null;


    /**
     * The cluster with which this Container is associated.
     */
    protected Cluster cluster = null;
    private final ReadWriteLock clusterLock = new ReentrantReadWriteLock();


    /**
     * The human-readable name of this Container.
     */
    protected String name = null;


    /**
     * The parent Container to which this Container is a child.
     */
    protected Container parent = null;


    /**
     * The parent class loader to be configured when we install a Loader.
     */
    protected ClassLoader parentClassLoader = null;
    ...(생략)..


3. 오해의 소지가 있는 주석 (Misleading Comments)

주석에 담긴 살짝 잘못된 정보 를 전달 할 수 있다.
아래의 코드에서는 this.closedtrue 로 변화하는 순간 메서드는 반환되지 않는다.
this.closedtrue 여야 메서드가 반환된다.
아니면 무조건 timeout 을 기다렸다가 this.closedtrue가 아니면 예외를 던진다.

// this.closed가 true일 때 반환되는 유틸리티 메서드다.
// 타임아웃에 도달하면 예외를 던진다.
public synchronized void waitForClose(final long timeoutMillis) throws Exception {
    if (!closed) {
        wait(timeoutMillis);
        if (!closed) {
            throw new Exception("MockResponseSender could not be closed");
        }
    }
}


4. 의무적인 주석 (Mandated Comments)

모든 함수에 Javadocs 를 달거나 모든 변수에 주석을 달아야 한다는 규칙은 어리석다.
이런 주석은 코드를 복잡하게 만들며, 혼동과 무질서를 초래한다.
아래와 같은 주석은 아무런 가치가 없다.

/**
 *
 * @param title CD 제목
 * @param author CD 저자
 * @param tracks CD 트랙 숫자
 * @param durationInMinutes CD 길이(단위: 분)
 */
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);
}


5. 이력 기록하는 주석 (Journal Comments)

Git 과 같은 소스 코드 관리 시스템이 있으니 전혀 필요 없다.

* 변경 이력 (11-Oct-2001 부터)
* ------------------------------------------------
* 11-Oct-2001 : 클래스를 다시 정리하고 새로운 패키징
* 05-Nov-2001: getDescription() 메소드 추가


6. 소음 주석, 있으나 마나 한 주석 (Noise Comments)

아무런 의미가 없는 주석이고, 오히려 코드를 읽을 때 주석을 그냥 지나치게 된다.

/*
 * 기본 생성자
 */
protected AnnualDateRule() {
}

/** 월 일 */
private int dayOfMonth;

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


아래 코드에서 첫 번째 주석이 의미가 있는데, 그냥 지나치게 된다.

private void startSending() {
    try {
        doSending();
    } catch(SocketException e) {
        // normal. someone stopped the request.
    } catch(Exception e) {
        try {
            response.add(ErrorResponder.makeExceptionString(e));
            response.closeAll();
        } catch(Exception e1) {
            //Give me a break!
        }
    }
}


7. 무서운 잡음 (Scary Noise)

Javadocs 또한 잡음이 될 수 있고, 문서를 제공하고자 하는 잘못된 욕구로 작성된 내용이다.

/** The name. */
private String name;

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

/** The licenceName. */
private String licenceName;

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


8. 함수나 변수로 표현할 수 있다면 주석을 달지 마라 (Don’t Use a Comment When You Can Use a Function of a Variable)

AS-IS TO-BE
// 전역 목록 smodule 에 속하는 모듈이 우리가 속한 하위 시스템에 의존하는가?
if (module.getDependSubsystems().contains(subSysMod.getSubSystem()))
ArrayList moduleDependencies = smodule.getDependSubSystems();
String ourSubSystem = subSysMod.getSubSystem();
if (moduleDependees.contains(ourSubSystem))


9. 위치를 표시하는 주석 (Position Markers)

가족성만 낮추므로 제거하는 것이 좋다. (특히, 뒷부분 슬래시)
너무 자주 사용하지 않을 때만 배너는 눈에 띄며 주위를 환기하므로, 반드시 필요할 때 아주 드물게 사용하는 것이 좋다.

// Actions /////////////////////////////////////////////


10. 괄호를 닫는 주석 (Closing Brace Comments)

중첩된 구조를 가진 긴 함수에 대해서는 의미가 있을 수도 있긴 하겠지만, 작고 캡슐화된 함수에서는 잡음일 뿐이다.
괄호를 닫는 주석을 달아야겠다는 생각 대신 함수를 줄이려는 시도를 하자.

public class wc {
    public static void main(String[] args) {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String line;
        int lineCount = 0;
        int charCount = 0;
        int wordCount = 0;
        try {
            while ((line = in.readLine()) != null) {
                lineCount++;
                charCount += line.length();
                String words[] = line.split("\\W");
                wordCount += words.length;
            } //while
            System.out.println("wordCount = " + wordCount);
            System.out.println("lineCount = " + lineCount);
            System.out.println("charCount = " + charCount);
        } // try
        catch (IOException e) {
            System.err.println("Error:" + e.getMessage());
        } //catch
    } //main
}


11. 공로를 돌리거나 저자를 표시하는 주석 (Attributions and Bylines)

Git 과 같은 소스 코드 제어 시스템으로 대체가 가능하다.

/* Added by Rick */


12. 주석으로 처리된 코드 (Commented-Out Code)

1960년대에는 주석으로 처리된 코드는 유용했지만, 소스 코드 관리 시스템을 쓰기 때문에 굳이 주석으로 처리할 필요는 없다.

this.bytePos = writeBytes(pngIdBytes, 0);
//hdrPos = bytePos;
writeHeader();
writeResolution();
//dataPos = bytePos;
if (writeImageData()) {
    wirteEnd();
    this.pngBytes = resizeByteArray(this.pngBytes, this.maxPos);
} else {
    this.pngBytes = null;
}
return this.pngBytes;


13. HTML 주석 (HTML Comments)

소스 코드 주석의 HTML 은 혐오스러운 것이다.
적절한 HTML 로 주석을 장식하는 것은 개발자가 아닌, IDE 나 Javadocs 와 같은 도구의 책임이어야 한다.


14. 전역 정보 (Nonlocal Information)

주석을 달아야 한다면 근처에 있는 코드만 기술하고, 시스템의 전반적인 정보를 기술하지 말라. 해당 시스템의 코드가 변해도 아래 주석이 변하리라는 보장은 전혀 없다. 그리고 심하게 중복된 주석도 확인하자.

/**
 * 적합성 테스트가 동작하는 포트: 기본값은 8082.
 *
 * @param fitnessePort
 */
public void setFitnessePort(int fitnessePort) {
    this.fitnewssePort = fitnessePort;
}


15. 많은 정보 (Too Much Information)

아래 주석은 base64 를 인코딩하고 디코딩 할 수 있는지 테스트 하기 위해 설계된 모듈에서 추출한 주석인데,
RFC 번호 이외에는 쓸모가 없다.

/*
    RFC 2045 - Multipurpose Internet Mail Extensions (MIME)
    Part One: Format of Internet Message Bodies
    section 6.8. Base64 Content-Transfer-Encoding
    The encoding process represents 24-bit groups of input bits as output
    strings of 4 encoded characters. Proceeding from left to right, a
    24-bit input group is formed by concatenating 3 8-bit input groups.
    These 24 bits are then treated as 4 concatenated 6-bit groups, each
    of which is translated into a single digit in the base64 alphabet.
    When encoding a bit stream via the base64 encoding, the bit stream
    must be presumed to be ordered with the most-significant-bit first.
    That is, the first bit in the stream will be the high-order bit in
    the first 8-bit byte, and the eighth bit will be the low-order bit in
    the first 8-bit byte, and so on.
*/


16. 모호한 관계 (Inobvious Connection)

주석과 그것이 묘사하는 코드 사이의 연관성은 명백해야 한다.
아래 코드에서 filter byte 란 무엇인가?, +1, *3, +200 인지.. 픽셀이 바이트인지 명확하지 않다.

/*
 * 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];


17. 함수 헤더 (Function Headers)

짧은 함수에는 많은 설명이 필요 하지 않다.
한 가지 작업을 수행하는 작은 함수에 대해 잘 선택된 이름은 일반적으로 주석 보다 낫다.


18. 비공개 코드의 Javadoc (Javadoc in Nonpulibc code)

시스템 내부의 클래스와 함수에 대한 Javadoc 페이지를 생성하는 것은 일반적으로 유용하지 않다.



Best practices for writing code comments


🍏 ️ About

stackoverflow blog 에서 소개된 코드 주석 작성 모범 사례를 정리한 내용 (보러가기)

유명한 MIT 교수인 Hal Abelson 은 아래와 같이 말했다.

“프로그램은 사람이 읽을 수 있도록 작성되어야 하며, 기계가 실행 할 수 있도록 부수적으로만 작성되어야 합니다”

나쁜 주석은 주석을 전혀 달지 않는 것보다 나쁘다.
Peter Vogel 은 아래와 같이 말한다.

  1. 주석을 작성하고 유지하는 것은 비용이 든다.
  2. 컴파일러는 주석을 확인하지 않으므로 주석이 올바른지 확인할 방법이 없다.
  3. 반면에, 컴퓨터가 코드 지시대로 정확히 수행하고 있다는 것을 보장 받을 수 있다.


규칙 1. 주석은 코드와 중복되어서는 안됩니다.


표준적인 나쁜 예

i = i + 1;         // Add one to i

이 경우, 어떠한 정보도 추가하지 않으며 유지 관리 비용이 발생한다.
모든 코드 줄에 주석을 요구하는 정책은 Reddit 에서 조롱되었다.

// create a for loop // <-- comment
for // start for loop
(   // round bracket
    // newline
int // type for declaration
i   // name for declaration
=   // assignment operator for declaration
0   // start value for i


규칙 2. 좋은 주석은 불분명한 코드를 변명하지 않습니다.

주석의 또 다른 오용은 코드에 있어야 할 정보를 제공하는 것이다.
n 이라는 변수 이름을 지정하고, 그 목적을 설명하는 주석을 추가하는 경우보다는
더 나은 변수 이름 지정으로 주석의 필요성이 제거 될 수 있다.

AS-IS TO-BE
private static Node getBestChildNode(Node node) {
    Node n; // best child node candidate
    for (Node node: node.getChildren()) {
        // update n if the current state is better
        if (n == null || utility(node) > utility(n)) {
            n = node;
        }
    }
    return n;
} 
private static Node getBestChildNode(Node node) {
    Node bestNode;
    for (Node currentNode: node.getChildren()) {
        if (bestNode == null || utility(currentNode) > utility(bestNode)) {
            bestNode = currentNode;
        }
    }
    return bestNode;
}


KernihhanPlauger 는 아래와 같이 말한다.

“나쁜 코드에 주석을 달지 말고 다시 작성하라”


규칙 3. 명확한 주석을 작성할 수 없다면 코드에 문제가 있을 수 있습니다.

유닉스 소스 코드에서 가장 악명 높은 주석은 “당신은 이것을 이해할 것으로 예상되지 않습니다” 인데,

/*
 * Switch to stack of the new process and set up
 * his segmentation registers.
 */
retu(rp->p_addr);
sureg();
/*
 * If the new process paused because it was
 * swapped out, set the stack level to the last call
 * to savu(u_ssav). This means that the return
 * which is executed immediately after the call to aretu
 * actually returns from the last routine which did
 * the savu.
 * You are not expected to understand this.
 */
if(rp->p_flag&SSWAP) {
    rp->p_flag =& ~SSWAP;
    aretu(u.u_ssav);
}
/*
 * The value returned here has many subtle implications.
 * See the newproc comments.
 */
return(1);

Dennis Ritchie 는 나중에 “뻔뻔한 도전이라기 보다는 ‘이건 시험에 나오지 않을 것’ 이라는 정신으로” 의도된 것이라고 설명했지만,
공동 저자인 Ken Thompson 은 이 내용을 이해하지 못하고 일주일 동안 디버깅하고, 결국 코드를 다시 작성했다.

Kernighan 의 법칙을 떠올리게 하는데,

“디버깅은 처음에 코드를 작성하는 것보다 두배나 어렵다. 따라서 코드를 가능한 한 영리하게 작성한다면 정의상 코드를 디버깅할 만큼 똑똑하지 않은 것이다.”

설명할 수 있을 만큼 충분히 설명하거나, 더 나은 방법으로 코드를 다시 작성해라.


규칙 4. 주석은 혼란을 야기하는 것이 아니라 혼란을 해소해야 합니다.

주석이 혼란을 야기 하는 경우 해당 주석을 삭제 해라.

Steven Levy 의 Hackers: Heroes of the Computer Revolution 에 나오는 다음 이야기가 없으면 나쁜 주석에 대한 논의가 완성되지 않을 것이다.
최초의 MIT 해커 중 한 명인 Peter Samson 이 작성한 프로그램 중 하나는 숫자 1750이 포함된 명령어 앞에 RIPJSB 라는 주석만 있었고,


누군가가 1750 이 표준이라는 것을 알아낼 때까지 그 의미에 대해서 고민했고,
Rest In Peace Johann Sebastian Bach 의 약어를 썼다.

[Peter Samson] was particularly obscure in refusing to add comments to his source code explaining what he was doing at a given time. One well-distributed program Samson wrote went on for hundreds of assembly-language instructions, with only one comment beside an instruction that contained the number 1750. The comment was RIPJSB, and people racked their brains about its meaning until someone figured out that 1750 was the year Bach died, and that Samson had written an abbreviation for Rest In Peace Johann Sebastian Bach.


규칙 5. 주석에서 단일 관용어 코드를 설명하세요.

App Inventor 의 코드에서 보면 다른 사람이 불필요하거나 중복된다고 생각할 수 있는 코드에 주석을 추가하는 것은 좋은 생각이다.
코드가 필요한 이유를 적어서 다른 사람의 시간과 불안을 절약해라.

final Object value = (new JSONTokener(jsonString)).nextValue();
// Note that JSONTokener.nextValue() may return
// a value equals() to null.
if (value == null || value.equals(null)) {
    return null;
}

단, 초보자를 위한 튜토리얼을 작성하지 않는 한, 일반적인 관용어에 대한 설명은 포함하지 않는 것이 좋다.


규칙 6. 복사된 코드의 원본 소스에 대한 링크를 제공하세요.

온라인에서 찾은 코드를 사용할 때가 있는데, 소스에 대한 참조를 포함하면 다른 개발자가 아래와 같은 전첵 맥락을 얻을 수 있다.

  • 어떤 문제가 해결되고 있었나요?
  • 코드를 제공한 사람
  • 솔루션이 권장되는 이유
  • 댓글 작성자가 어떻게 생각했는지
  • 아직도 작동하는지
  • 어떻게 개선될 수 있는가

이 코드를 이해하려는 사람은 공식을 검색해야 하는데, 나중에 참조를 찾는 것보다 URL 을 붙여 넣는 것이 훨씬 빠르다.

// Magical formula taken from a stackoverflow post, reputedly related to
// human vision perception.
return (int) (0.3 * red + 0.59 * green + 0.11 * blue);

단, 이해하지 못하는 코드를 붙여넣어서는 안된다.
Copying code from Stack Overflow? You might paste security vulnerabilities, too


규칙 7. 가장 도움이 될 외부 참조 링크를 포함하세요.

표준 및 기타 문서에 대한 링크는 코드에서 해결하는 문제를 이해하는 데 도움이 될 수 있다.
예제로, 아래의 링크를 따라가면, RFC 4180RFC 7111 에 의해 업데이트 되었음을 나타낸다.

// http://tools.ietf.org/html/rfc4180 suggests that CSV lines
// should be terminated by CRLF, hence the \r\n.
csvStringBuilder.append("\r\n");


규칙 8. 버그를 수정할 때 주석을 추가하세요.

주석은 코드를 처음 작성할 때 뿐만 아니라, 수정시, 특히 버그를 수정할 때에도 추가해야 한다.
아래의 주석은 메서드의 코드를 이해하는데 도움이 될 뿐만 아니라 코드가 여전히 필요한지 여부와 테스트 방법을 결정하는 데도 도움이 된다.

// NOTE: At least in Firefox 2, if the user drags outside of the browser window,
// mouse-move (and even mouse-down) events will not be received until
// the user drags back inside the window. A workaround for this issue
// exists in the implementation for onMouseLeave().
@Override
public void onMouseMove(Widget sender, int x, int y) { .. }


규칙 9. 불완전한 구현을 표시하려면 주석을 사용하세요.

알려진 제한 사항이 있음에도 불구하고 코드를 사용해야 하는 경우가 있는데, 코드의 알려진 결함을 공유 하지 않는게 좋겠지만,
TODO 주석과 같이 이를 명시적으로 만드는게 좋다.

// TODO(hal): We are making the decimal separator be a period,
// regardless of the locale of the phone. We need to think about
// how to allow comma as decimal separator, which will require
// updating number parsing and other places that transform numbers
// to strings, such as FormatAsDecimal

주석이 잘못된 코드를 변명하거나 수정하지 않는다는 점을 알 수 있다.
다른 유형의 정보를 제공하여 좋은 코드를 보완한다.


Summary

Stack Overflow 의 공동 창립자인 Jeff Atwood 는 아래와 같이 말한다.Code Tells You How, Comments Tell You Why

“코드는 방법을 알려주고, 주석은 이유를 알려줍니다”

이러한 규칙을 따르면 시간과 좌절감을 줄일 수 있다.


📗 개인적인 생각

📣 의무적인 Javadoc 은 없어도 된다. (Clean Code Bad Comments 6, 7, 18)
📣 API 중에서 특수한 경우 (parameter 에 대한 주석이 필요할 때) Javadoc 으로 작성하면 가독성이 좋다.
🖐 반드시 best practices 를 따를 필요는 없으므로!!)
📣 설명이나 정보를 알려주는 주석은 반드시 필요하다. (Clean Code Good Comments 2, 3, 4)
🖐 혼란을 야기하는 내용은 안된다. (Best Practices for writing code comments 규칙 4)
🖐 너무 많은 정보를 담지 않아야 한다. (Clean Code Bad Comments 15)
📣 TODO 주석은 필요한 경우만 달자. (Clean Code Good Comments 6)
📣 참고한 코드의 링크를 추가하는 것이 좋다. (Best Practices for writing code comments 규칙 6, 7)
📣 버그로 인한 수정할 때 주석을 추가 하자. (Best Practices for writing code comments 규칙 8)
📣 변수 명이나 메서드 명을 명확히 한다면 주석을 작성하는 일이 줄어 들 것 같다...!



Reference