[Effective Java] 아이템 56 - 공개된 API 요소에는 항상 문서화 주석을 작성하라
개요
쓸모 있는 API에는 잘 작성된 문서도 필요하다.
API 문서는 사람이 직접 작성하므로, 코드의 변경 시 매번 함께 수정해줘야 하는데 자바에서는 자바독(javadoc)이라는 유틸리티가 도와준다.
Javadoc : 소스코드 파일에서 문서화 주석이라는 특수한 형태로 기술된 설명을 추려 API 문서로 변환해준다.
API의 올바른 문서화를 위해서는 공개된 모든 클래스, 인터페이스, 메서드, 필드 선언에 문서화 주석을 달아야한다.
직렬화할 수 있는 클래스라면 직렬화 형태에 관해서도 적어야 한다.
문서화 주석이 없다면 자바독도 그저 공개 API 요소들의 '선언'만 나열해주는게 전부이다.
문서화 주석 기본 규칙
메서드용 문서화 주석에는 해당 메서드와 클라이언트 사이의 규약을 명료하게 기술해야 한다.
상속용으로 설계된 클래스의 메소드가 아니라면 그 메소드가 어떻게 동작하는 것인지(how)가 아닌, 무엇을 하는지(what)를 기술해야 한다
문서화 주석에는 클라이언트가 해당 메소드를 호출하기 위한 전제조건을 모두 나열 해야 한다.
또한 메소드가 성공적으로 수행된 후에 만족해야 하는 사후조건도 모두 나열 해야 한다.
일반적으로 전제조건은 @throws 태그로 비검사 예외를 선언하여 암시적으로 기술한다.
비검사 예외 하나가 전제조건 하나와 연결되는 것이다.
또한, @param 태그를 이용해 그 조건에 영향받는 매개변수에 기술할 수 도 있다.
문서화 주석에는 전제조건과 사후조건 뿐만 아니라 부작용도 문서화 해야 한다.
부작용? 사후조건으로 명확히 나타나지는 않지만 시스템의 상태에 어떠한 변화를 가져오는 것을 말한다.
ex) 백그라운드 스레드를 시작시키는 메소드라면 그 사실을 문서에 밝혀야 한다.
메소드의 계약을 완벽히 기술하려면 모든 매개변수에는 @param태그를, 반환 타입이 void가 아니라면 @return 태그를, 발생할 가능성이 있는 모든 예외에는 @throws 태그를 달아야 한다.
(코드 표준에서 허락한다면 @return 태그의 설명이 메소드 설명과 같은 경우 생략 가능)
관례상 @param 태그와 @return 태그의 설명은 해당 매개변수가 뜻하는 값이나 반환값을 설명하는 명사구를 쓴다.
드물게는 명사구 대신 산술 표현식을 쓰기도 한다. -> full sentence 보다는 예를 들어 index of element to return; 식으로
문서화 주석에 HTML 태그(<p>와 <i>)를 쓴 점 주목
자바독 유틸리티는 문서화 주석을 HTML로 변환하므로 문서화 주석 안의 HTML 요소들이 최종 HTML 문서에 반영된다.
@throws 절에 사용한 {@code} 태그도 살펴보자.
효과는 크게 두가지로 볼 수 있다.
첫번째, 태그로 감싼 내용을 코드용 폰트로 랜더링한다.
두번째, 태그로 감싼 내용에 포함된 HTML 요소나 다른 자바독 태그를 무시한다. 이로 인해 HTML 메타문자인 태그 기호등을 별다른 처리 없이 바로 사용할 수 있다.
문서화 주석에 여러 줄로 된 코드 예시를 넣으려면 {@code} 태그를 다시 <pre> 태그로 감싸면 된다.
이렇게 하면 HTML의 탈출 메타문자를 쓰지 않아도 코드의 줄바꿈이 그대로 유지된다.
단 @ 기호에는 무조건 탈출 문자를 붙여야하니 문서화 주석 안의 코드에서 어노테이션을 사용한다면 주의하자
주석에서 사용되되는 'this' 는 인스턴스의 메소드가 자리하는 객체를 의미한다.
@implSpec 태그
클래스를 상속용으로 설계할 때는 자기사용 패턴(self-use pattern)에 대해서도 문서에 남겨 다른 프로그래머에게 그 메소드를 올바로 재정의하는 방법을 알려줘야 한다.
자기사용 패턴은 자바 8에서 추가된 @impleSpec 태그로 문서화한다.
@impleSpec 주석은 해당 메소드와 하위 클래스 사이의 계약을 설명하여, 하위 클래스들이 그 메소드를 상속하거나 super 키워드를 이용해 호출할 때 그 메소드가 어떻게 동작하는지를 명확히 인지하고 사용하도록 해줘야 한다.
@literal 태그
API 설명에 <, >, & 등의 HTML 메타문자를 포함시키려면 특별한 처리를 해줘야 함을 잊지 말자.
가장 좋은 방법은 {@literal} 태그로 감싸는 것이다.
이 태그는 HTML 마크업이나 자바독 태그를 무시하게 해준다. {@code} 태그와 비슷하지만 코드 폰트로 랜더링하지 않는다.
요약설명(summary description) 주석
각 문서화 주석의 첫 번째 문장은 해당 요소의 요약 설명(summary description)으로 간주된다.
요약 설명은 반드시 대상의 기능을 고유하게 기술해야 한다.
따라서 헷갈리지 않으려면, 한 클래스(혹은 인터페이스) 안에서 요약 설명이 똑같은 멤버(혹은 생성자)가 둘 이상이면 안된다.
-> 다중 정의된 메소드 주의
요약 설명에서는 마침표(.)를 주의해서 사용하자.
요약 설명이 끝나는 판단 기준은 처음 발견되는 {<마침표><공백><다음 문장 시작>} 패턴의 마침표까지이다.
요약 설명 주석 내에 마침표를 사용해야 되는 경우에는 @literal 태그를 사용하자.
*요약 설명이란 문서화 주석의 첫 문장이다 라고 말하면 살짝 오해의 소지가 있다. 주석 작성 규약에 따르면 요약 설명은 완전한 문장이 되는 경우가 드물기 때문이다. 메소드와 생성자의 요약설명은 해당 메소드와 생성장의 동작을 설명하는 (주어가 없는) 동사구여야 한다.
@index 태그
자바 9부터는 자바독이 생성한 HTML 문서에 검색(색인) 기능이 추가되어 광대한 API 문서에서 검색으로 접근하기가 용이해졌다.
클래스, 메소드, 필드 같은 API 요소의 색인은 자동으로 만들어지며, 원한다면 @index 태그를 사용하여 API에 중요한 용어를 추가로 색인화 할 수 있다.
제네릭, 열거 타입, 어노테이션, 패키지
문서화 주석에서 제네릭, 열거 타입, 어노테이션은 특별히 주의해야 한다.
제네릭 타입이나 제네릭 메소드를 문서화할 때는 모든 타입 매개변수에 주석을 달아야 한다.
ex)
열거 타입을 문서화할 때는 상수들에도 주석을 달아야 한다.
열거 타입 자체와 그 열거 타입의 Public 메소드도 주석 처리해줘야 한다.
설명이 짧다면 주석 전체를 한 문장으로 써도 된다.
어노테이션 타입을 문서화할 때는 멤버들에도 모두 주석을 달아야 한다. 어노테이션 타입 자체도!
필드 설명은 명사구로 진행한다.
어노테이션 타입의 요약 설명은 프로그램 요소에 이 어노테이션을 단다는 것이 어떤 의미인지를 설명하는 동사구로 한다.
패키지를 설명하는 문서화 주석은 package-info.java 파일에 작성한다.
이 파일은 패키지 선언을 반드시 포함해야 하며 패키지 선언 관련 어노테이션을 추가로 포함할 수도 있다.
자주 누락되는 설명
크게 두가지가 있다.
1. 스레드 안전성
2. 직렬화 가능성
클래스 혹은 정적 메소드가 스레드 안전하든 그렇지 않든, 스레드 안전 수준을 반드시 API 설명에 포함해야 한다.
또한, 직렬화할 수 있는 클래스라면 직렬화 형태도 API 설명에 기술해야 한다.
자바독은 메소드 주석을 '상속'시킬 수 있다. 문서화 주석이 없는 API 요소를 발견하면 자바독이 가장 가까운 문서화 주석을 찾아준다.
이때 상위 '클래스'보다 그 클래스가 구현한 '인터페이스'를 먼저 찾는다.
{@inheritDoc} 태그를 사용해 상위 타입의 문서화 주석 일부를 상속할 수 있다.
<inheritdoc [cref="link-ref"] [select="filter-expr"] />
핵심 정리
문서화 주석은 여러분 API를 문서화하는 가장 훌륭하고 효과적인 방법이다. 공개 API라면 빠짐없이 설명을 달아야 한다.
표준 규약을 일관되게 지키자.
문서화 주석이 임의의 HTML 태그를 사용할 수 있음을 기억하라
단, HTML 메타문자는 특별하게 취급해줘야 한다.