왜 필요한가?
팀원들과, 특히 백엔드끼리 협업을 하면서 설계를 끝내고 구현으로 들어가면서
가장 먼저 맞닥들인 문제는 “컨벤션” 이었다.
주위에 물어보니 그게 무슨 문제가 되고 왜 정해야 하는지 이해를 못하는 사람들도 있었지만,
같은 프로젝트의 코드를 건드리는 팀원의 입장에서
다른 사람이 쓴 코드를 이해하는 데에 시간이 걸리거나
하다못해 DTO 의 클래스 이름부터가 뭐하는 DTO 인지 알기 어렵다면,
같이 코드를 작성하는 데에 불편함이 있다.
그래서 프로젝트를 같이 하는 팀원과 컨벤션을 정하고 코드 작성을 시작하기로 했다.
코드 스타일에 표준이라는 것은 없지만, 팀 내부에서 같은 코드 스타일을 결정하고 유지하는 것이
작업 효율을 높일 것이라고 생각했다.
그리고 유지보수 !
내가 코드를 계속 작성하고 고쳐나갈 수 있다면 좋겠지만,
누군가 새로운 사람이 투입됐을 때 어떤 코드 규칙이 있다면 그 엔지니어가 코드를 이해하는 데에
도움이 될 것이다.
코딩 컨벤션이란
프로그래밍 언어는 말 그대로 언어. 한국어, 영어와 비슷하다.
지역마다 사투리가 있듯 프로그래밍 세계에서도 스타일이라는 것이 존재한다.
스타일이 다르다는 것은 틀린 것은 아니지만, 통일된 기준으로 코드를 작성해야
소통이 원활하다.
어떤 코딩 컨벤션을 선택한다는 것은 “우리는 경상도식 사투리로 가자” 는 것과 유사한 것 같다.
1. IDE 를 활용해 코딩 컨벤션 적용하기
우리 팀은 IntelliJ + mac OS 를 사용했기 때문에 그 기준으로 작성해보았다.
여기서는 Naver Campus Hackday 컨벤션을 사용했다.
아래 링크에서 xml 파일을 다운로드하거나 xml 파일을 만들고 내용을 복붙하자.
GitHub - naver/hackday-conventions-java: 캠퍼스 핵데이 Java 코딩 컨벤션
캠퍼스 핵데이 Java 코딩 컨벤션. Contribute to naver/hackday-conventions-java development by creating an account on GitHub.
github.com
IntelliJ 에서 preferences
-> Editor
-> code style
로 들어가서 적용하자.
이제 코드를 작성하고 command
+ option
+ L
을 누르면 자동으로 코드가 포맷에 맞게 수정된다.
+ 추가
IntelliJ 에 있는 플러그인을 적용하자
CheckStyle 이라는 플러그인을 이용하면 룰에 어긋나는 코드에 대해 알림 메시지를 띄워준다.
투머치라고 생각되면 스킵 ㅎ.
install 하고 나면 preferences
-> Tools
→ CheckStyle
→ +
버튼을 선택해서
아래 링크에 있는 파일을 저장 후 새로운 CheckStyle 을 생성하자.
https://github.com/naver/hackday-conventions-java/blob/master/rule-config/naver-checkstyle-rules.xml
GitHub - naver/hackday-conventions-java: 캠퍼스 핵데이 Java 코딩 컨벤션
캠퍼스 핵데이 Java 코딩 컨벤션. Contribute to naver/hackday-conventions-java development by creating an account on GitHub.
github.com
아마 Property 로 suppressionFile 을 설정하라고 뜰텐데,
검사 대상에서 제외할 파일을 선택하는 설정이다.
제외 대상이 없이 그대로 진행하면 에러가 뜨니, 나는 이 설정을 삭제하고 진행했다.
삭제하는 방법은 naver-checkstyle-rules.xml 파일을 열고 아래 부분을 삭제하자.
이제 생성한 CheckStyle 을 선택하고 Apply
하자.
CheckStyle 이 적용되면 자동으로 룰에 어긋나는 부분을 보여준다.
하단 CheckStyle 탭을 보면 아래에 메시지가 뜬다.
너무 보기 싫다면 설정에서 Active 를 꺼두면 된다.
위에서 초록색 재생 버튼을 클릭하거나 파일을 열고 우클릭해서 Check Current File
을 클릭하면
검사를 실시한다.
2. 네이밍 결정하기
- 변수는 CamelCase 를 기본으로 한다.
- userEmail
- URL, 파일명은 kebab-case 를 사용한다.
- /user-email-page
- 패키지명은 단어가 달라지더라도 무조건 소문자를 사용한다.
- frontend, useremail
- ENUM 이나 상수는 대문자를 사용한다.
- NORMAL_STATUS
- 함수명은 소문자로 시작하고 동사로 네이밍한다.
- getUserId(), isNormal()
- 클래스명은 명사로 네이밍하고 UpperCamelCase 를 사용한다.
- UserEmail
- 객체 이름을 함수 이름에 중복해서 넣지 않는다.
- line.getLength()
O
/ line.getLineLength()X
- line.getLength()
- 컬렉션은 복수형을 사용하거나 컬렉션을 명시해준다.
- List ids, Map<User, Integer> userToIdMap
- 이중적인 의미를 가지는 단어는 지양한다.
- event, design
- 의도가 드러난다면 되도록 짧은 이름을 선택한다.
- retreiveUser()
X
/ getUser()O
- retreiveUser()
- 함수의 부수효과를 설명한다.
- 위 함수의 경우 단순히 order 만 가져오는 것이 아니라, 없으면 생성해서 리턴
- 따라서 getOrder()
X
/ getOrCreateOrder()O
public Order getOrder() {
if (order == null) {
order = Order()
}
return order;
}
- LocalDateTime → xxxAt, LocalDate → Dt 로 네이밍
- 객체를 조회하는 함수는 JPA Repository 에서 findXXX 형식의 네이밍 쿼리메소드를 사용하므라
개발자가 작성하는 Service 단에서는 되도록 getXXX 를 사용한다.
위 항목들이 기본적으로 지킬 규칙들이다.
구체적으로 Controller 와 Service 에서 사용할 메소드의 네이밍은 아래 규칙을 따른다.
Controller
orderList()
: 목록 조회orderDetails()
: 단건 상세 조회orderSave()
: 등록/수정/삭제가 동시에 일어나는 메소드orderAdd()
: 등록orderModify()
: 수정orderRemove()
: 삭제
Service
getOrders()
: 목록 조회getOrder()
: 단건 조회addOrder()
: 등록modifyOrder()
: 수정removeOrder()
: 삭제saveOrder()
: 등록/수정/삭제가 동시에 일어나는 메소드
DTO
도메인별로 상위 DTO 를 하나 만들어서 Inner Class 들로 관리한다.
User 도메인에서 이를 관리하는 경우 아래와 같은 방식
public class User {
@Getter
@AllArgsConstructor
@Builder
public static class Info {
private int id;
private String name;
private int age;
}
@Getter
public static class Request {
private String name;
private int age;
}
@Getter
@AllArgsConstructor
public static class Response {
private Info info;
private int returnCode;
private String returnMessage;
}
}
이미 프로젝트에서 CommonResponse
객체를 만들어서 사용하고 있다면,
도메인 DTO InnerClass 에 Request
, Response
등의 네이밍은 지양한다.
참고글 ⬇️
https://google.github.io/styleguide/javaguide.html
https://naver.github.io/hackday-conventions-java/