클린코드 책과 제로베이스 [개발자와 함께 읽는 클린코드] 강좌를 기반으로 작성하였습니다.
주석
이번 챕터에서는 4가지 주제로 설명을 해보려고 한다.
- 주석을 최대한 쓰지 말자
- 좋은 주석
- 주석보다 어노테이션
- JavaDoc
01. 주석을 최대한 쓰지 말자
책에서는 일단 주석을 사용하는 것을 지양하도록 설명하고 있다. 지양하는 이유는 올바른 주석을 활용하기가 생각보다 어렵기 때문이다. 올바른 주석은 그 어떤 정보보다 유용하지만 대부분의 주석은 그러하지 못하다.
주석은 나쁜 코드를 보안하지 못한다.
코드에 주석을 추가하는 이유는 일반적으로 코드품질이 나쁘기 때문이다. 코드품질이 나쁘다는 것은 코드만으로 본인이 작성한 로직을 설명하지 못한다는 의미이다. 이렇다 보니 주석으로 코드의 의도를 표현하는 경우가 발생한다.
// 직원에게 복지 혜택을 받을 자격이 있는지 검사한다.
if ((employee.flags & HOURLY_FLAG) && employee.age > 65))
// 의미있는 이름으로 지으면 해결된다.
if (employee.isEligibleForFullBenefits())
위 코드를 첫번째 라인의 코드를 보면 코드만으로는 조건절의 의도를 파악하기가 어렵다. 그렇기 때문에 주석을 추가하여 부가설명을 하였다. 하지만 이러한 경우 주석을 달지 말고 의미 있는 이름을 짓는 등의 개선을 진행(코드로 의도를 표현하라!)하는 것이 시간이 걸리더라도 더 좋은 방법이다.
왜?
간단한 로직에 주석을 부가설명을 하는 것이 왜 안좋은 것이냐 생각할 수 있다. 만약 복지 혜택을 받는 조건을 늘어난다거나 연금 혜택 기준 같은 조건이 추가된다면 문제가 발생할 수 있다.
바로 주석을 코드의 변화에 맞추어 최신화해줘야 하기 때문이다. 코드는 컴파일되어 호촐되지만, 주석을 그저 텍스트이다. 그렇기 때문에 변경하지 않고 방치될 가능성이 농후하다. 그러면 주석은 부정확해지고 아예 없는 것만도 못하게 된다.
02. 좋은 주석
주석을 사용하는 것을 자제하라고 하지만 아예 사용하지 못하는 것은 어렵다. 이런 경우 좋은 주석을 사용하면 된다.
구현에 대한 정보를 제공한다.
// kk:mm:ss EEE, MMM dd, yyyy 형식
Pattern timeFormat = Pattern.complie("\\d*:\\d:\\d* \\w*, \\w* \\d* \\d*");
위 코드는 시각과 날짜에 대한 정규식을 나타낸다고 주석으로 표기하고 있다. 해당 정규식 코드를 시각과 날짜로 변환하는 클래스를 만들어 코드를 옮겨주면 주석 없이 표현할 수 있다고 한다. 하지만 정규표현식 자체가 한눈에 알아보기는 쉽지가 않다. 그런 경우 위와 같이 주석을 통해 정보를 제공하는 것은 좋은 주석이라고 할 수 있다.
의도의 중요성을 설명한다.
때떄로 주석은 구현에 대한 설명을 넘어서 의도까지 설명하기도 한다.
// 스레드를 많이 생성하여 시스템에 영향을 끼쳐 테스트를 만들도록 한다.
for (int i = 0; i < 25000; i++) {
SomeThread someThread = ThreadBuilder.builder().build();
}
// 유저로부터 입력받을 값을 저장할 때 trim으로 공백제거 필요
String userName = userNameInput.trim();
상단 코드를 보면 반복문을 통해 스레드를 반복 생성하고 있는데 그것에 대한 의도를 주석을 표현해 주면 읽는 사람에게 도움을 줄 수 있다. 물론 메서드를 만들어 표현할 수 있지만 테스트코드라는 가정 하면 간단히 주석으로 의도를 표현하여 많이 사용한다.
아래 코드는 유저의 이름을 받을 때 trim을 사용해야 되는 의도의 중요성을 설명해주고 있다.
TODO, FIXME 주석
// TODO
// FIXME
- TODO : 앞으로 할 일, 지금은 해결하지 않지만 나중에 해야할 일을 미리 적어둘 때 사용
- FIXME : 문제가 있지만, 당장 수정할 필요는 없을 때, 가능하면 빨리 수정하는 게 좋다.
해당 주석들은 IDE에서 하이라이팅되고, 별로의 윈도에서 볼 수 있다.
하지만 주석과 마찬가지로 개발자가 확인하지 않으면 문제가 될 수 있으므로 사용을 자제하라고 하기도 한다. 주기적으로 TODO/FIXME 주석을 점검하여 없애는 작업을 하기를 권장한다.
03. 주석보단 어노테이션 (결과를 경고하는 주석 대체)
어노테이션은 코드에 대한 메타 데이터이며, 코드의 실행 흐름에 간섭을 주기도 하고, 주석처럼 코드에 대한 정보도 줄 수 있다.
@Deprecated : 컴파일러가 warning을 발생시키고, IDE에서 사용 시 표기가 된다.
@NotThreadSafe : Thread Safe하지 않음을 나타낸다. (책에서는 주석으로 표기했지만 어노테이션으로 많이 사용된다.)
04. JavaDoc
// This is a single line comment
/*
* This is a regular multi-line comment
*/
/**
* This is a Javadoc
*/
자바독은 기본적으로 /** 로 시작하는 주석을 의미하며, HTML Tag를 포함할 수 있다.
Class Level
/**
* Hero is the main entity we'll be using to . . .
*
* Please see the {@link com.baeldung.javadoc.Person} class for true identity
* @author Captain America
*
*/
public class SuperHero extends Person {
// fields and methods
}
클래스 선언 코드위에 작성되며 클래스에 대한 설명과 상세정보를 표현한다.
상세정보에는 @author어노테이션을 이용해 코드 작성자를 표기하거나 @Link를 걸어 상세내용에 대한 하이퍼링크롤 생성하기도 한다. (여기서 Person의 Link는 자세한 내용을 참조하라는 의미.)
Field Level
/**
* The public name of a hero that is common knowledge
*/
private String heroName;
이 필드가 무엇을 뜻하는지 표현한다.
Method Level
/**
* <p>This is a simple description of the method. . .
* <a href="http://www.supermanisthegreatest.com">Superman!</a>
* </p>
* @param incomingDamage the amount of incoming damage
* @return the amount of health hero has after attack
* @see <a href="http://www.link_to_jira/HERO-402">HERO-402</a>
* @since 1.0
*/
public int successfullyAttacked(int incomingDamage) {
// do things
return 0;
}
JavaDoc는 HTML 스타일을 지원하므로 <p><a> 태그등을 사용할 수 있으면 메서드 레벨에서는 파라미터의 대한 정의와 리턴의 정의 등을 기술한다.
각 레벨에 맞게 JavaDoc를 사용하면 아래와 같이 문서로 나타낼 수 있다.
자바독을 사용하는 이유
외부에서 사용될 가능성이 있는 코드(라이브러리, 오픈 API 화)들은 작성한 사람 뿐아니라 외부에서도 사용되기 때문에 주석을 통해 의도나 구현을 설명할 필요가 있다. 그런 경우 javadoc 패턴에 맞춰 클래스나 메서드를 대해 자세한 주석을 남긴다. 외부에서 사용되지 않는 서비스 코드에서 클래스정도에만 간단하게 작성하기도 한다.
// 간단간단하게 클래스 설명(클래스명에서 의도가 표현된다면 이것도 생략)로 사용된다.
/**
* @author jaehy
*
* 중계수수료가 얼마인지 조회하는 컨트롤러
*/
@RestController
public class BrokerageQueryController {
@GetMapping("/api/calc/brokerage")
public Long calcBrokerage(@RequestParam ActionType actionType, @RequestParam Long price) {
BrokeragePolicy policy = BrokeragePolicyFactory.of(actionType);
return policy.calculate(price);
}
}
하지만 마찬가지로 잘 작성된 javadoc도 변화에 맞추지 않으면 쓸모없는 주석이 될 수 있으니 잘 관리할 필요가 있다. 그리고 꼭 필요한 부분이 아닌 모든 클래스, 메서드에 의무적으로 작성하거나 변경 이력을 다 남기는 등(실제 전 회사에서 이런 식의 기준이 있었다.)으로 활용된다면 일반 주석과 차이가 없어져 javadoc 기능을 제대로 수행하지 못한다.
그 외의 나쁜 주석은 뭐가 있을까?
- 주석에 변경이력을 다 기록하는 행위
- 옛날에는 해당 방식을 많이 이용했다. (회사에서 옛날 코드를 열어보면 실제로 이런 경우가 많다.) 하지만 형상관리툴이 발달된 지금 불필요한 행위이다.
- 의무적으로 작성한 주석
- javadoc에서 설명한 것처럼 모든 클래스, 메서드에 의무적으로 달아.라고 한다면 마찬가지로 주석을 다 형상관리하는 문제가 발생되며 방치되는 주석이 많아진다.
- 있으나 마다한 주석
- 코드를 보다보면 라인 별로 모든 설명을 다 주석으로 적은 코드를 본 적이 있을 것이다. 이런 주석은 코드를 더럽게 만들고 어지럽게 한다.
- 그 외에도 닫는 괄호를 표기하는 주석이라던지 주절하거는 주석(은어나 본인 생각 등)은 사용하지 말 것
'Language > TDD, 클린코드, 리펙토링' 카테고리의 다른 글
[클린코드] 3장. 함수 (with SOLID) (2) | 2023.12.11 |
---|---|
[클린코드] 1장 깨끗한 코드, 2장 의미있는 이름을 읽고 정리한 내용 (0) | 2023.12.07 |
[TDD] getter 대신 메시지를 던져라 (0) | 2023.09.03 |
[TDD] 테스트가 힘든 코드를 테스트 가능한 구조로 변경하기 (0) | 2023.08.29 |