-
Notifications
You must be signed in to change notification settings - Fork 0
3.4. 코드 컨벤션
-
CRUD 메서드 네이밍
-
Controller, Service
- createCustomer
- findCustomerById
- findAllCustomers
- updateCustomer
- deleteCustomerById
-
Repository
- save
- findById
- findAll
- existsById
- update
- 특정 컬럼만 수정하는 경우에는
updateCustomerNameByCustomerId
형식
- 특정 컬럼만 수정하는 경우에는
- deleteById
-
-
DTO 네이밍
-
요청
: 도메인 + 동작 + Request (ex. CustomerCreateRequest.java) -
응답
:- 도메인 + Response (ex. CustomerResponse.java)
- 도메인 + 필드(한 단어) + Response (ex. CustomerIdResponse.java)
-
Wrapper
- ApiResponse.java
-
-
예외 클래스 네이밍
-
도메인 + exception
(ex. CustomerException.java)
-
-
예외 규칙 및 메시지 네이밍
- 사용자 입력이 유효성 검사에 통과하지 못한 경우
-
상태코드
: 400 BAD_REQUEST -
객체명
: COMMON_BAD_REQUEST -
에러코드
: COM-002 -
메시지
: “사용자 입력 유효성 검사 실패”
-
- 요청 URL에 대한 자원이 존재하지 않는 경우
-
상태코드
: 404 NOT_FOUND -
객체명
: 도메인 + NOT_EXIST (ex. CUSTOMER_NOT_EXIST) -
에러코드
: CUS-001 -
메시지
: “해당 고객이 존재하지 않음”
-
- 잘못된 HTTP Method 요청
-
상태코드
: 405 METHOD_NOT_ALLOWED -
객체명
: COMMON_METHOD_NOT_ALLOWED -
에러코드
: COM-003 -
메시지
: “허용되지 않은 HTTP Method 요청 발생”
-
- 기타
-
상태코드
: 500 INTERNAL_SERVER_ERROR -
객체명
: COMMON_INTERNAL_SERVER_ERROR -
에러코드
: COM-004 -
메시지
: “기타 서버 내부 에러 발생”
-
- 사용자 입력이 유효성 검사에 통과하지 못한 경우
-
변수 네이밍
-
변수명에는 자료구조의 이름이 들어가지 않는다. 단 Map과 같은 특수한 자료형은 붙여서 작성한다.
[NO] customerList [YES] customers customerMap
-
메서드 매개변수 네이밍
-
DTO가 매개변수로 들어갈 때는 축약하지 않는다.
public ApiResponse<ScheduleResponse> createSchedule( @RequestBody ScheduleCreateRequest scheduleCreateRequest, ) { ... }
-
-
-
테스트 메서드
-
DisplayName
- 동사로 끝낸다
- 대상 + 실행 + 기대값
- 예)
사용자가 회원가입을 하면 고객정보가 정상적으로 저장된다.
-
메서드 네이밍
메서드명_(조건)_기대결과
언더바(_) 기준으로 메서드명을 나누고, 언더바 뒤의 단어 첫글자는 대문자-
성공(조건이 X)
- createCustomer_Success
-
실패
- findCustomerById_NotExistedId_Null
- createCustomer_InvalidPassword_ThrowException (예외 발생 시)
-
-
-
포매터 → 네이버 캠퍼스 핵데이 컨벤션
-
객체지향 생활 체조 원칙을 지키려고 노력
[Java] 객체지향 생활 체조 원칙 9가지 (from 소트웍스 앤솔러지)
- 한 메서드에 오직 한 단계의 들여쓰기(indent)만 한다.
- else 예약어를 쓰지 않는다.
- 모든 원시 값과 문자열을 포장한다.
- 일급 컬렉션을 쓴다.
- 한 줄에 점을 하나만 찍는다.
- 줄여 쓰지 않는다(축약 금지).
- 모든 엔티티를 작게 유지한다.
- 3개 이상의 인스턴스 변수를 가진 클래스를 쓰지 않는다.
- getter/setter/프로퍼티를 쓰지 않는다.
-
Primitive type 대신 Wrapper type으로 통일 (int → Integer)
-
class의 첫 줄은 개행한다. (마지막 줄은 개행 하지 않는다.)
public class Schedule { private Long scheduleId; ... }
-
@Builder
- 모든 필드가 빌더에 사용되면 클래스 단위
- 일부분의 필드가 빌더에 사용되면 생성자 단위
-
생성자 매개변수 2개 이상이면 빌더 패턴, 1개면 정적 팩토리 메서드(from)를 사용한다.
- from : 매개변수 1개
- 빌더패턴 : 매개변수 2개 이상
-
CRUD 반환 값 (물론 컨트롤러에서 반환할 때 id 하나만 있더라도 responseDto로 감싸서 반환)
- CREATE → dto(CustomerIdResponse)
- READ → dto, List
- UPDATE → dto
- DELETE → void
-
매개변수가 많아지면 아래로 개행한다.
public ApiResponse<ScheduleResponse> createSchedule( @PathVariable Long performanceId, @RequestBody ScheduleCreateRequest request, HttpServletRequest httpServletRequest ) { ... }
-
애너테이션 순서는 성질이 비슷한 것끼리 그룹화 하고 그 안에서 길이 순으로 정렬한다.
@RestController @RequiredArgsConstructor @RequestMapping("/api/performances/{performanceId}")
-
import
순서는 기본 포매터에게 맡긴다. -
SQL 쿼리문의 키워드(
SELECT
,INSERT
,UPDATE
,DELETE
등)는 대문자로 쓴다.- ON, JOIN, AND, OR, AS, IN, ORDER BY, GROUP BY, HAVING, WHERE, FROM …
-
return
,throw
문의 경우 한 줄 개행해서 작성하여 가독성을 높인다. (단, 코드 블럭 내에 해당 문장이 단 한줄만 있는 경우에는 붙여서 작성한다.)// 한 줄 개행하여 작성 public List<RankingResponse> findTopRankingPerformances() { String key = RankingScheduler.getTopRankingCacheKey(); return redisTemplate.opsForValue() .get(key); }
// 한 메서드 내에 return이나 throw 한 문장만 있으면 붙여서 작성 public List<RankingResponse> findTopRankingPerformances() { return redisTemplate.opsForValue() .get(RankingScheduler.getTopRankingCacheKey()); }
-
변하지 않을 것 같은 매개변수, 필드 등 모두 final을 사용하여 방어적 코딩을 한다.
- 여기에 더해서 유틸 클래스에는 final 키워드를 붙인다.
- 수직 거리 지키기