STUDY/Books

[Clean Code] 4장 주석

hyunah 2021. 5. 16. 10:26

Clean Code 스터디 내용 정리; 4장 주석


주석의 불필요성과 좋은 주석, 나쁜 주석의 구체적인 예시에 대해 다룬다. 이 글에서는 그 중에서 주석과 좋은 주석의 내용에 대해 정리하였다.



주석은 필요악


코드 자체로 의미가 충분히 전달된다면 주석은 전혀 필요하지 않다. 주석은 코드만으로 표현할 방법을 찾지 못해 할 수 없이 사용하게 되는 것이다.
따라서 주석이 필요한 상황에 처하면 코드로 의도를 표현할 방법이 정말 없는지 곰곰이 생각해보자. 주석은 가능한 줄이도록 노력하자.

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


if (employee.isEligibleForFullBenefits()) // 코드만으로 충분히 표현할 수 있음


저자는 프로그래머들이 주석까지 유지보수하기란 사실상 불가능하기에 시간이 지남에 따라 주석은 코드에서 멀어지게 될 수밖에 없고, 부정확한 정보를 전달하는 주석은 없느니만 못하다고 말한다. 주석을 엄격하게 관리할 바에야 코드를 깔끔하게 정리하여 표현력을 강화하는 것이 더 낫다는 것이다.







좋은 주석


그럼에도 불구하고 어떤 주석은 필요하거나 유익하다. 그러나 정말 좋은 주석은 없는 주석임을 명심하자.




1. 법적 주석
회사의 구현 표준에 맞춰 법적인 이유로 첨부하는 주석. 저작권 정보, 소유권 정보 등을 밝힌다.




2. 정보 제공하는 주석

기본적인 정보를 제공하는 주석. 편리하고 유용할 때도 있지만 가능하다면 함수 이름에 정보를 담는 편이 더 좋긴 하다.

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


protected abstract Responder responderingBeingTested(); // 함수 이름에 정보를 담음



3. 의도 설명하는 주석

결정에 깔린 의도와 이유를 설명한다.

private static int determineIterationLimit()
{
    // 배열에 있는 모든 배수는 배열 크기의 제곱근보다 작은 소수의 인수다.
    // 따라서 이 제곱근보다 더 큰 숫자의 배수는 제거할 필요가 없다.
    double iterationLimit = Math.sqrt(crossedOut.length);
    return (int) iterationLimit;
}



4. 의미를 명료히 하는 주석

인수나 반환값의 의미를 명료히 밝히는 주석. 인수나 반환값 자체를 의미가 명확히 드러나도록 만들면 더 좋지만, 표준 라이브러리나 변경하지 못하는 코드인 경우에 사용. 필요한 주석이지만 주석이 올바른지 검증하기 쉽지 않기에 위험하다.

assertTrue(a.compareTo(a) == 0); // a == a
assertTrue(aa.compareTo(ab) == -1); // aa < ab



5. 결과를 경고하는 주석

다른 프로그래머에게 결과를 경고할 목적으로 사용하는 주석.

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 주석을 점검해 필요없는 것은 제거하는 편이 좋다.

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



7. 중요성 강조하는 주석
대수롭지 않다고 여겨질 수도 있는 것의 중요성을 강조하기 위해 쓰는 주석

String listItemContent = match.group(3).trim()
// 여기서 trim은 정말 중요하다. trim 함수는 문자열에서 시작 공백을 제거한다.
// 문자열에 시작 공백이 있으면 다른 문자열로 인식되기 때문이다.



8. 공개 API에서 Javadocs
공개 API를 구현한다면 반드시 훌륭한 Javadocs를 작성해야 한다. 그러나 Javadocs 역시 그릇된 정보를 전달할 가능성이 존재한다는 것을 명심해야 한다.







나쁜 주석


대부분의 주석이 나쁘다. 대다수 주석은 프로그래머가 주절거리는 독백에서 크게 벗어나지 못한다.




1. 제 역할을 하지 못하는 주석
코드를 제대로 설명하지 못해 읽는 사람이 이해할 수 없는 주석. 주석과 주석이 설명하는 코드 사이의 관계가 명백하지 않아서 주석 자체가 다시 설명을 요구하는 경우에 해당. 코드 명확하게 설명하지 않아 코드를 오해할 여지가 있는 주석 또한 여기에 해당. 주석을 달기로 했다면 충분히 숙고하여 코드를 명백히 설명하는 최고의 주석을 달도록 하자.

/*
* 모든 픽셀을 담을 만큼 충분한 배열로 시작한다(여기에 필터 바이트를 더한다).
* 그리고 헤더 정보를 위해 200바이트를 더한다.
*/
this.pngBytes = new byte[((this.width+1) * this.hegith * 3) + 200];  // 주석으로도 코드를 온전히 이해할 수 없음



2. 정보가 없는 주석
코드의 내용을 그대로 중복하는 주석이나 너무 당연한 사실을 언급하는 주석. 주석이 코드보다 더 많은 정보를 제공하지 못하며 나중에는 거짓말하는 주석이 될 가능성이 높다. 모든 함수나 변수에 주석을 달아야 한다는 규칙은 이런 주석을 양성할 우려가 있기에 좋지 않다.

//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")l
    }
}


/**
*이 컴포넌트를 지원하기 위한 생명주기 이벤트
*/
protected LifecycleSupport lifecycle = new LifecycleSupport(this);


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



3. 주석으로 표현할 필요가 없는 주석
소스코드 관리 시스템이 저장하는 모듈의 수정사항이나 작성자, 삭제된 코드를 기록하거나, 코드를 개선하는 방법으로 충분히 표현할 수 있는 주석. 함수를 설명하는, 닫힌 괄호에 다는 주석이나 함수 헤더를 설명한 주석도 이 경우에 해당. 긴 함수와 그를 설명하는 주석보다는, 짧고 이름 잘 붙인 함수와 없는 주석이 훨씬 낫다.

// 전역 목록 <smodule>에 속하는 모듈이 우리가 속한 하위 시스템에 의존하는가?
if (smodule.getDependSubsystems().contains(subSysMod.getSubSystem()))


// 다음과 같이 코드를 개선해 표현할 수 있음
ArrayList module Dependees = smodule.getDependSubsystems();
String ourSubSystem = subSysMod.getSubSystem();
if (moduleDependees.contains(ourSubSystem))



4. 코드와 관련 없는 주석
근처에 있는 코드만 기술하는 게 아니라 시스템 전반의 정보를 기술하는 주석이나 역사와 같이 관련 없는 정보를 늘어놓는 주석.




5. 위치를 표시하는 주석
소스 파일에서 특정 위치를 표시하려 사용하는 주석은 유용한 경우도 있지만 너무 자주 사용하면 읽는 사람이 잡음으로 여겨 무시하게 되기 때문에 반드시 필요할 때만 아주 드물게 사용하는 편이 좋다.




6. 비공개 코드에서 Javadocs
공개 API가 아니라 비공개 코드라면 Javadocs는 쓸모가 없다. 오히려 코드가 보기 힘들어질 뿐이다.






이제까지 정보가 없는 주석만 줄기차게 달아왔던 프로그래머로서 많이 반성하였다. 주석은 코드 자체를 설명하는 것이 아니라 코드의 이해를 도와주는 용도라는 것을 명심하고, 주석을 달아야겠다는 생각이 든다면 (내 코드를 남이 이해하기 힘들겠다는 생각이 든다면) 코드를 개선할 방법을 궁리하는 습관을 들여야겠다.

'STUDY > Books' 카테고리의 다른 글

[Clean Code] 6장 객체와 자료 구조  (0) 2021.05.21
[Clean Code] 5장 형식 맞추기  (0) 2021.05.18
[Clean Code] 3장 : 함수  (0) 2021.05.11
[Clean Code] 2장 : 의미 있는 이름  (0) 2021.05.07
[Clean Code] 1장 : 깨끗한 코드  (0) 2021.05.05