주석은 나쁜 코드를 보완하지 못한다.
- 코드에 주석을 추가하는 일반적인 이유는 코드 품질이 나쁘기 때문이다.
- 모듈을 짜고 보니 알아보기 어렵다면 주석을 다는 것이아니라 알아보기 쉽게 다시 코드를 정리해야 한다.
코드로 의도를 표현하라
- 주석으로 코드를 설명하기 전에 코드만으로 의미를 포함할 수 있는 방법이 없는지 생각해봐야한다.
//직원에게 복지 혜택을 받을 자격이 있는지 검사한다.
if((employee.flags & HOURLY_FLAG) &&
(employee.age>65))
- 위와 같은 코드는 아래와 같이 바꿀 수 있다.
if(employee.isEligibleForFullBenefits())
- 위의 코드를 보면 충분히 의도를 파악할 수 있다.
좋은 주석
법적인 주석
- 법적인 이유로 특정 주석을 넣으라고 명시하는 경우 주석을 다는 것은 좋은 주석에 속한다.
정보를 제공하는 주석
- 기본적인 정보를 주석으로 제공하면 편리한 경우가 있다.
//테스트 중인 Responder 인스턴스를 반환한다.
protected abstract Responder responderInstance();
- 물론 위의 경우도 아래와 같이 함수 이름에 정보를 담는 편이 좀더 좋다.
protected abstract Responder responderBeingTested();
의도를 설명하는 주석
- 코드를 짜면서 자신이 결정한 방식에 대해서 그 의도를 설명하는 주석을 말한다.
- 예를들어, 두 객체를 비교할 때 어떤 객체보다 자기 객체에 높은 우선순위를 주고싶다면, 그 의도를 설명하는 주석을 달아두는 것은 바람직하다.
public int compareTo(Object o){
if(o instanceof WikiPagePath){
//...
}
// 해당 경우에는 우선순위가 높다.
return 1;
}
public void testConcurrentAddWidgets() {
//...
// 스레드를 대량 생성하는 방법으로 경쟁 조건을 만든다.
for (int i = 0; i < 25000; i++){
new Thread(widgetBuilderThread).start();
}
//...
}
의미를 명료하게 밝히는 주석
- 때때로 아래와 같이 모호한 인수나 반환값은 그 의미를 읽기 좋게 표현하면 이해하기 쉬운 경우가 있다.
assertTrue(a.compareTo(a) == 0); // a == a
결과를 경고하는 주석
- 다은 프로그래머에게 결과를 경고하는 목적으로 작성된 주석은 유용하게 쓰일 수 있다.
// 여유 시간이 충분하지 않다면 실행하지 마십시오.
public void testWithReallyBigFile() {
//...
}
TODO 주석
- 더 이상 필요 없는 기능을 삭제하라는 알림의 경우 유용하다.
- 누군가에게 문제를 봐달라는 요청의 경우 유용하다.
- 앞으로 발생할 이벤트에 맞춰 코드를 고치라는 주의 표시하는 경우 유용하다.
- 하지만 나쁜 코드를 남겨 놓는 핑계로 사용해서는 안된다.
중요성을 강조하는 주석
- 자칫 대수롭지 않다고 여겨질 뭔가의 중요성을 강조하기 위한 용도라면 좋은 주석이다.
String listItemContent = match.group(3).trim();
// 여기서 trim으로 시작공백을 제거함으로써 다른 문자열로 인식될 위험을 제거합니다.
new ListItemWidget(this, listItemContent, this.level + 1);
공개 API에서 Javadocs
- 설명이 잘 된 공개 API는 참으로 유용하다.
- 표준 자바 라이브러리에서 사용한 javadocs가 좋은 예다.
- 하지만 반드시 훌륭한 javadocs를 작성해야 한다.
나쁜 주석
주절거리는 주석
- 특별한 이유 없이 의무감으로 다는 주석은 바이트 낭비일 뿐이다.
- 주석을 달기로 결정했다면 충분한 시간을 들여 최고의 주석을 달도록 노력하자.
같은 이야기를 중복하는 주석
- 이런 주석은 자칫하면 코드보다 주석을 읽는 시간이 더 오래 걸린다.
// this.closed가 true일 때 반환되는 유틸리티 메서드다.
// 타임아웃에 도달하면 예외를 던진다.
public synchronized void waitForClose(final long timeoutMillis) throws Exception{
if(!closed) {
wait(timeoutMillis);
if(!closed)
throw new Exception("~~");
}
}
/**
* 컨테이너와 관련된 Loader 구현
*/
protected Loader loader = null;
/**
* 컨테이너와 관련된 Logger 구현
*/
protected Log logger = null;
/**
* 컨테이너와 관련된 logger 이름
*/
protected String logName = null;
오해할 여지가 있는 주석
- 때때로 의도는 좋았으나 프로그래머가 딱 맞을 정도로 엄밀하게는 주석을 달지 못하는 경우가 있다.
- 이런경우 오히려 주석으로 인해서 코드를 오해할 수 있다.
- 그렇기 때문에 주석을 작성할때는 신중하게 의도가 정확히 기술 되었는지 생각해 봐야한다.
의무적으로 다는 주석
- 예를들어, 아래와 같이 모든 변수에 주석을 달아야 한다는 규칙은 어리석다.
/*
@param tite CD 제목
@param author CD 저자
@param tracks CD 트랙 숫자
*/
public void addCD(String title, String author, int tracks) {
CD cd = new CD();
cd.title = title;
cd.author = author;
cd.tracks = tracks;
}
- 오히려 이런 주석은 코드를 복잡하게 만들고 혼동과 무질서를 초래한다.
이력을 남기는 주석
- 소스 코드를 관리할 수 있는 시스템이 많은 지금 가장 필요없는 주석중 하나이다.
있으나 마나 한 주석
- 아래와 같이 너무 당연한 사실이기 때문에 전혀 유익한 정보를 제공하지 못하는 주석을 말한다.
/**
* 기본 생성자
*/
protected AnnualDateRule() {
}
/** 월 중 일자 */
private int dayOfMonth;
/**
* 월 중 일자를 반환한다.
*
* @return 월 중 일자
*/
public int getDayOfMonth() {
return dayOfMonth;
}
- 이런 주석은 개발자가 다른 주석까지 무시하는 습관을 만들 수 있다.
무서운 잡음
- 아래와 같이 수행하는 목적이 없이 작성된 주석을 말한다.
//The name
private String name;
//The version
private String version;
함수나 변수로 표현할 수 있다면 주석을 달지 마라
- 위에서도 언급했듯이 코드로 의미를 표현할 수 있다면, 주석을 달지 않고 의미를 표현하는 것이 좋다.
// 전역 목록 <smodule>에 속하는 모듈이 우리가 속한 하위 시스템에 의존하는가?
if (smodule.getDependSubsystems().contains(subSysMod.getSubSystem()))
- 위의 코드는 아래와 같이 코드만으로 의미를 표현할 수 있다.
ArrayList moduleDependees = smodule.getDependSubsystems();
String ourSubSystem = subSysMod.getSubSystem();
if (moduleDependees.contains(ourSubSystem))
위치를 표시하는 주석
- 때때로 아래와 같이 소스 파일에서 특정 위치를 표시하려 주석을 사용하는 경우가 있다.
// Actions //////////////////////////////
- 하지만 반드시 필요한 경우, 아주 드물게 사용하는 편이 좋은 경우가 있다.
닫는 괄호에 다는 주석
try {
while ((line = in.readLine()) != null) {
} //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
}
공로를 돌리거나 저자를 표시하는 주석
- 이 또한 이력을 남길 수 있는 시스템이 만은 경우 불필요한 주석이다.
주석으로 처리한 코드
- 주석으로 처리된 코드는 다른 사람들이 지우기를 주저한다.
- 이유가 있어서 남겨놓았으리라고, 중요하니까 지우면 안 된다고 생각한다.
- 그렇기 때문에 주석으로 남기는 코드는 없는것이 바람직 하다.
전역 정보
- 주석을 달아야 한다면 근처에 있는 코드만 기술하는 것이 좋다.
- 코드 일부에 주석을 달면서 시스템의 전반적인 정보를 기술하지 않은 것이 좋다.
/*
적합성 테스트가 동작하는 포트 : 기본값은 <b>8082</b>
@param fitnessePort
*/
public void setFitnessePort(int fitnessePort) {
this.fitnessPort = fitnessePort;
}
너무 많은 정보
- 주석에다 흥미로운 역사나 관련 없는 정보를 장황하게 늘어놓지 않는 것이 좋다.
모호한 관계
- 주석과 주석이 설명하는 코드는 둘 사이 관계가 명백해야 한다.
- 코드만으로 설명이 부족할 때 주석이 코드의 부족한 설명을 채우는 방식으로 작성되어야 한다.
- 주석 자체가 다시 설명을 요구해서는 안된다.
비공개 코드에서 Javadocs
- 공개 API는 javadocs가 유용하지만 공개하지 않을 코드라면 쓸모없는 주석에 불가하다.
- 오히려 코드가 산만해 진다.
REFERENCES
- 클린코드 4장
'Books' 카테고리의 다른 글
클린코드 8장 (0) | 2022.04.23 |
---|---|
클린코드 6장 (객체와 자료구조) (0) | 2022.04.23 |
클린코드 3장 (함수) (0) | 2022.04.17 |
클린코드 1장, 2장 (0) | 2022.04.17 |
템플릿 콜백 패턴 (토비의 스프링 3장) (0) | 2022.02.28 |