주석의 종류
1. 문서화 주석 (Documentation Comments)
- 형식: /** ... */ 또는 언어별 문서화 도구 형식
- 목적: API 문서 자동 생성, 공개 인터페이스 설명
- 대상: 클래스, 함수, 메서드의 공개 인터페이스
- 내용: 기능 설명, 매개변수, 반환값, 예외, 사용 예시
/**
* 사용자 정보를 데이터베이스에서 조회합니다.
*
* @param userId 조회할 사용자의 고유 ID (양수여야 함)
* @return 사용자 정보 객체, 없으면 null
* @throws IllegalArgumentException userId가 0 이하일 때
*/
fun getUserById(userId: Int): User?
2. 비형식 주석 (Informal Comments)
- 형식: // (한 줄) 또는 /* ... */ (여러 줄)
- 목적: 구현의 의도나 이유 설명
- 대상: 코드 내부 로직, 복잡한 알고리즘
- 내용: "왜" 이렇게 구현했는지, 특별한 고려사항
// 캐시 무효화를 위해 타임스탬프 갱신 (버그 #1234 해결)
cache.updateTimestamp()
/*
* 성능 최적화: 정렬 대신 해시맵 사용
* 벤치마크 결과 10배 빠름 (10,000개 기준)
*/
val lookup = items.associateBy { it.id }
주석의 목적
1. 코드 이해 속도 향상
언제 필요한가:
- 복잡한 알고리즘 (ex: 그래프 탐색, 동적 프로그래밍)
- 난해한 라이브러리나 프레임워크 사용
- 비즈니스 로직이 복잡한 경우
작성 방법:
- 높은 수준의 개요: "이 함수는 X를 위해 Y 방식을 사용합니다"
- 단계별 세분화: 큰 로직을 섹션으로 나누어 설명
- 구체적 예시: 입출력 예시로 이해도 향상
/**
* 다익스트라 알고리즘으로 최단 경로를 찾습니다.
*
* 예시:
* 그래프: A --5--> B --3--> C
* findPath(A, C) → [A, B, C] (거리: 8)
*/
fun findShortestPath(start: Node, end: Node): List<Node> {
// 1. 우선순위 큐 초기화 - 가장 가까운 노드부터 탐색
val queue = PriorityQueue<Node>()
// 2. 방문한 노드 기록 - 중복 탐색 방지
val visited = mutableSetOf<Node>()
// 3. 경로 추적을 위한 맵
val parent = mutableMapOf<Node, Node>()
}
2. 실수 방지
중요 정보:
- 경계 조건: 입력값의 범위, null 허용 여부
- 제약 조건: 호출 순서, 스레드 안전성
- 부작용: 상태 변경, 외부 리소스 사용
- 위반 시 결과: 예외 발생, 데이터 손상 등
/**
* 배치 처리를 시작합니다.
*
* 주의사항:
* - 반드시 init() 호출 후 사용해야 함
* - 동시에 하나의 스레드만 실행 가능 (스레드 안전하지 않음)
* - items는 최소 1개 이상이어야 함 (빈 리스트 시 IllegalArgumentException)
*
* @throws IllegalStateException init()을 먼저 호출하지 않은 경우
*/
fun processBatch(items: List<Item>)
3. 리팩토링 지원
리팩토링 시 유용한 주석:
- 코드의 의도나 목적 명시 → 동작을 유지하면서 구조 개선 가능
- 최적화 이유 설명 → 성능 저하 없이 리팩토링
- 특정 구현을 선택한 배경 → 잘못된 리팩토링 방지
// 주의: Stream API 대신 for문 사용 (성능상 2배 빠름, 벤치마크 결과 참조)
// 리팩토링 시 성능 테스트 필수
for (item in largeList) {
process(item)
}
4. 특수 목적 주석
작업 관리:
// TODO: 에러 핸들링 추가 필요
// FIXME: 메모리 누수 발생 (issue #456)
// HACK: 임시 해결책, API 업데이트 후 제거 예정
// NOTE: 이 부분은 외부 팀과 협의 후 변경 불가
IDE 기능 활용:
// region 사용자 인증 관련
fun login() { }
fun logout() { }
// endregion
메타프로그래밍:
@Deprecated("Use newFunction() instead")
@SuppressWarnings("unchecked")
// @Generated("Auto-generated by MyTool v1.2")
❌ 주석 안티패턴 (피해야 할 것들)
1. 자동 생성된 문서 방치
// 나쁜 예
/**
* @param param1
* @param param2
* @return
*/
fun calculate(param1: Int, param2: Int): Int
문제점: 내용 없는 껍데기만 있어 혼란만 가중
2. 선언 내용 반복
// 나쁜 예
// userId를 설정합니다
fun setUserId(userId: Int)
// 좋은 예 - 추가 정보 제공
// 사용자 ID를 설정합니다 (1 이상의 양수만 허용)
fun setUserId(userId: Int)
3. 코드를 자연어로 직역
// 나쁜 예
// i가 10보다 작으면 i에 1을 더한다
if (i < 10) i++
// 좋은 예 - 의도 설명
// 페이지당 최대 10개 항목만 표시
if (i < 10) i++
4. 개요 없이 세부사항만 나열
// 나쁜 예
// 먼저 데이터베이스에 연결하고
// 쿼리를 실행한 다음
// 결과를 파싱하고...
// 좋은 예
// 사용자 프로필을 데이터베이스에서 로드하여 UI 모델로 변환
// 1. DB 연결 및 쿼리
// 2. 결과 파싱
// 3. UI 모델 변환
5. 구현 세부사항 언급
// 나쁜 예
// UserService의 getUserById()를 호출하고
// 내부적으로 HashMap에서 조회함
// 좋은 예
// 사용자 정보를 ID로 조회 (캐시 우선 확인)
이유: 내부 구현은 변경될 수 있으므로 사용자는 알 필요 없음
6. 코드 사용처 언급
// 나쁜 예
// LoginActivity에서 호출됨
fun authenticate(username: String, password: String)
이유: 호출 관계는 IDE로 확인 가능하며, 변경 시 주석도 수정해야 함
💡효과적인 주석 작성 팁
- "무엇"이 아닌 "왜"를 설명: 코드 자체가 "무엇"을 보여주므로
- 간결하게: 장황한 설명보다 핵심만 전달
- 최신 상태 유지: 코드 변경 시 주석도 함께 업데이트
- 코드로 표현 우선: 주석이 필요 없을 만큼 명확한 코드가 최선
- 일관된 형식: 팀 내 컨벤션 통일
// 좋은 주석의 예
/**
* 결제 처리 후 재고를 차감합니다.
*
* 중요: 트랜잭션 내에서만 호출해야 합니다.
* 재고 부족 시 롤백을 위해 예외를 발생시킵니다.
*
* @throws InsufficientStockException 재고가 부족한 경우
*/
fun deductInventory(productId: String, quantity: Int)
'Devlog > 공부 아카이브' 카테고리의 다른 글
| [리뷰하기 좋은 코드 작성] 상태 관리와 코드 설계 (0) | 2025.12.21 |
|---|---|
| [스프링 부트 정리] 스프링 부트 자세히 살펴보기 (0) | 2025.10.06 |
| [스프링 부트 정리] Spring JDBC 자동 구성 개발 (0) | 2025.10.06 |
| [스프링 부트 정리] 외부 설정을 이용한 자동 구성 (0) | 2025.10.06 |
| [스프링 부트 정리] 조건부 자동 구성 (0) | 2025.10.06 |