Java/Spring 코드 설명과 주석 표준
- 상태:
approved - 적용 대상: 이 포트폴리오에서 새로 작성하거나 의미 있게 수정하는 Java/Spring 코드. 다른 저장소에서는 언어, 공개 범위와 검증 도구를 해당 프로젝트에 맞게 조정한다.
- 목적: 처음 코드를 읽는 사람이 업무 규칙, 신뢰 경계, 실패 방식과 변경 영향을 코드 가까이에서 판단할 수 있게 한다.
1. 기본 원칙
코드는 이름과 구조로 무엇을 하는지 보여주고, Javadoc과 주석은 코드만으로 알기 어려운 왜 그렇게 해야 하는지를 설명한다.
| 코드가 우선 보여줄 내용 | 설명이 보완할 내용 |
|---|---|
| 타입, 메서드와 변수의 역할 | 업무 규칙과 설계 의도 |
| 실행 순서와 분기 | 해당 순서와 분기가 필요한 이유 |
| 예외 발생 지점 | 실패 시 보호하려는 상태와 외부 계약 |
| 트랜잭션과 저장 호출 | 원자성, 재시도와 동시성 기준 |
| 인증과 권한 검사 | 신뢰 경계와 정보 노출 방지 기준 |
| 외부 API 호출 | timeout, 검증, fallback과 부작용 정책 |
설명은 좋은 이름, 작은 메서드, 설계 문서와 테스트를 대체하지 않는다. 설명이 길어져야만 이해되는 메서드는 먼저 역할 분리가 필요한지 검토한다.
2. 언어와 공개 안전성
- 설명 문장은 한글로 작성하고 클래스명, 메서드명, 라이브러리명, 프로토콜명과 상태값은 코드의 영문 식별자를 유지한다.
- 고객사명, 내부 조직명, 비공개 저장소명과 경로, 내부 URL, 실제 계정, 인증정보, 운영 데이터와 회사 소스는 포함하지 않는다.
- 업무 경험을 설명할 때는 합성 데이터와 일반화한 도메인으로 독립 재구성한다.
- 아직 검증하지 않은 동작이나 운영 성과를 완료된 사실처럼 설명하지 않는다.
3. 타입 수준 Javadoc
업무 책임이 있는 클래스와 인터페이스에는 타입의 지속적인 계약을 설명하는 Javadoc을 작성한다. 다음 중 해당하는 내용을 포함한다.
- 목적과 책임
- 주요 입력과 출력 또는 협력 객체
- 핵심 업무, 보안 및 데이터 기준
- 실패 시 동작과 부작용
- 변경 시 함께 확인할 테스트와 문서
/**
* 신뢰할 수 없는 자연어 요청을 검증된 구매 요청 초안으로 변환하는 서비스.
*
* <p><strong>입력/출력:</strong> 사용자 요청과 서버가 조회한 정책 근거를 받아
* 아직 승인되지 않은 초안을 반환한다.
*
* <p><strong>핵심 기준:</strong> 모델은 초안만 제안하며 승인, 상태 전이와
* 저장 가능 여부는 애플리케이션과 도메인 규칙이 최종 결정한다.
*
* <p><strong>수정 시 주의:</strong> 정책 근거 범위나 모델 출력 계약을 바꾸면
* 구조 검증, 실패 시나리오 테스트와 아키텍처 문서를 함께 확인한다.
*/
public class PurchaseDraftService {
}
단순 설정 값 묶음이나 한 가지 값만 전달하는 record도 단위, null 허용 여부 또는 신뢰 수준처럼 이름만으로 알기 어려운 계약이 있으면 타입 수준에서 설명한다.
4. 메서드 수준 Javadoc
다음 메서드는 목적, 입력, 출력, 예외와 변경 영향을 필요한 범위에서 설명한다.
- Controller의 공개 API와 애플리케이션 서비스 진입점
- 상태를 바꾸는 도메인 메서드
- 권한, 객체 접근, 개인정보 또는 정보 노출을 결정하는 메서드
- 트랜잭션, 멱등성, 잠금과 동시성 규칙이 있는 메서드
- DB, 파일, 메시지 브로커, LLM과 외부 API를 읽거나 쓰는 메서드
- 단위, 시간대, 식별자, 금액 또는 외부 응답을 변환하는 메서드
- 이름만으로 판단하기 어려운 업무 규칙이 들어간 private 메서드
/**
* 같은 요청자의 재시도를 하나의 구매 초안으로 수렴시킨다.
*
* <p>같은 멱등성 키와 같은 입력이면 기존 결과를 반환하고, 같은 키에 다른 입력이
* 들어오면 기존 결과를 덮어쓰지 않고 충돌로 중단한다.
*
* @param idempotencyKey 재시도 사이에 유지되는 요청 식별키
* @param requestText 신뢰할 수 없는 자연어 구매 요청
* @return 새로 생성했거나 동일 입력으로 확인한 구매 요청
* @throws IdempotencyConflictException 같은 키가 다른 입력에 사용된 경우
*/
public PurchaseRequest createDraft(String idempotencyKey, String requestText) {
// 구현 생략
}
다음 항목은 별도 설명을 생략할 수 있다.
- 단순 getter와 setter
- 필드 대입만 하는 생성자
- record가 자동 생성하는 접근자
- 프레임워크 관례와 이름만으로 계약이 분명한 단순 Repository 메서드
- 한 줄 위임 메서드와 표준 라이브러리 사용이 명확한 코드
설명을 생략할 수 있다는 것은 타입의 업무 계약까지 생략해도 된다는 뜻이 아니다.
5. 인라인 주석
인라인 주석은 코드 바로 옆에 있어야 이해되는 다음 내용을 설명할 때만 사용한다.
- 코드만으로 드러나지 않는 업무 기준
- 보안 또는 데이터 처리 이유
- 동시성, 재시도와 트랜잭션 제약
- 특정 순서를 지켜야 하는 이유
- 변경 시 영향을 받는 다른 계약
- 외부 시스템 제약 때문에 필요한 우회와 제거 조건
나쁜 예시는 코드를 그대로 읽어 줄 뿐이다.
// 구매 요청을 저장한다.
repository.save(request);
좋은 예시는 해당 저장 순서가 필요한 이유를 알려 준다.
// 승인 상태와 감사 이벤트를 같은 트랜잭션에 묶어 한쪽만 남는 상태를 방지한다.
repository.save(request);
동시성 처리는 다음처럼 최종 판정 기준을 설명한다.
// 애플리케이션 선조회만으로는 최초 요청끼리의 경합을 제거할 수 없다.
// DB 유니크 제약 충돌 후 승자 레코드를 다시 읽어 입력이 같은지 확인한다.
6. Spring 계층별 설명 기준
| 계층 | 우선 설명할 내용 | 반복하지 않을 내용 |
|---|---|---|
| Controller/API | 신뢰하지 않는 입력, 인증 주체, 응답의 정보 노출 경계 | URL과 HTTP method를 annotation 그대로 풀이 |
| Application Service | 업무 흐름, 트랜잭션 경계, 멱등성과 경합 처리 | 호출 순서를 줄마다 번역 |
| Domain | 허용 상태 전이, 불변조건, 자기 승인 같은 금지 규칙 | getter와 단순 필드 대입 |
| Persistence | 유니크 제약, 잠금, 조회 결과의 업무 의미 | Spring Data 메서드명의 단순 번역 |
| External Adapter | 프로토콜 계약, timeout, 출력 검증, fallback과 재시도 정책 | HTTP 호출 문법 자체 |
| Security | 역할과 객체 권한의 분리, 존재 여부 은닉, 세션과 CSRF 전제 | 보안 설정 DSL의 줄별 해설 |
| Configuration | 안전한 기본값, 필수 secret, 환경별 변경 제한 | 프로퍼티 이름의 한글 번역 |
| Test | 경합, 롤백과 실패 주입의 의도 | Given/When/Then 각 줄의 동작 반복 |
테스트는 이름과 @DisplayName으로 시나리오를 먼저 드러낸다. 주석은 테스트 장치가 실제 운영에서 발생 가능한 어떤 경합이나 실패를 재현하는지 추가 설명할 때만 사용한다.
7. 작성하지 않는 설명
- 코드가 하는 일을 그대로 반복하는 주석
- 실제 동작과 맞지 않는 오래된 설명
1단계,2단계처럼 번호만 붙인 주석- 담당자, 근거와 종료 조건이 없는
TODO - 주석 처리한 이전 코드
- 빈 Javadoc과 의미 없는
TODO문장 - 테스트로 확인하지 않은 성능, 보안 또는 운영 보장
- 설명을 길게 붙여 복잡한 메서드와 부정확한 이름을 유지하는 방식
임시 우회가 꼭 필요하면 원인, 적용 범위, 제거 조건과 추적할 issue를 함께 남긴다.
8. 변경 시 동기화 기준
다음 항목을 변경하면 관련 Javadoc과 주석을 같은 변경에서 검토한다.
- 상태 전이와 역할별 권한
- 트랜잭션 경계와 저장 순서
- 멱등성 키, 유니크 제약과 잠금 방식
- 외부 API, LLM 출력 schema, timeout과 fallback 정책
- 오류 코드와 외부 응답 계약
- 데이터 보존, 감사 이벤트와 민감정보 처리
설명과 구현이 충돌하면 구현을 무조건 정답으로 간주하지 않는다. 테스트와 설계 문서를 함께 확인해 의도한 계약을 결정한 뒤 코드 또는 설명을 수정한다.
9. 작업 순서
- 설계 문서와 테스트에서 의도한 업무 계약을 확인한다.
- 보안, 상태 변경, 외부 I/O, 트랜잭션과 동시성 코드부터 설명 대상을 선정한다.
- 타입 수준 설명으로 책임과 경계를 먼저 기록한다.
- 공개 진입점과 업무 규칙 메서드에 필요한 Javadoc을 추가한다.
- 코드 가까이에 있어야 의미가 있는 이유만 인라인 주석으로 남긴다.
- 단순 동작 반복, 오래된 설명과 공개하면 안 되는 정보를 제거한다.
- 관련 테스트와 문서를 실행하고 최종 diff에서 설명과 구현을 함께 검토한다.
10. 검수 체크리스트
- 중요한 타입의 목적, 핵심 기준과 변경 주의사항을 처음 읽는 사람이 파악할 수 있다.
- 상태 변경, 권한, 외부 I/O, 멱등성과 동시성 메서드의 계약이 설명되어 있다.
- 인라인 주석은
무엇보다왜, 제약과 변경 영향을 설명한다. - 단순 getter, 생성자와 자명한 코드에 불필요한 설명이 없다.
- 설명이 현재 코드, 테스트, README와 아키텍처 문서에 일치한다.
- 고객 식별정보, 내부 경로, 인증정보, 운영 데이터와 회사 코드가 없다.
- 아직 검증하지 않은 동작을 보장한다고 표현하지 않는다.
- 관련 단위, 통합 및 실패 시나리오 테스트가 통과한다.
Javadoc 누락 여부는 Checkstyle 규칙이나 저장소별 커스텀 검사로 확인할 수 있다. 태그, 링크와 문법은 Javadoc/doclint 생성 단계에서 검사한다. 다만 설명이 실제 업무 의도와 맞는지는 자동 검사만으로 보장할 수 없으므로 코드 리뷰와 동작 테스트를 함께 사용한다.