Why
이번에 새로이 PG프로젝트가 진행되었다. 그러나 프로젝트 시작 시 미리 코딩컨벤션에 대한 이야기가 되어있지 않았다. 그래서 각 프로젝트 마다 각기 다른 코딩스타일로 작성이 되어버렸다. 이를 통일하기 위해서 Java를 위한 코딩 컨벤션을 정의하고자 한다.
Defined Rules
Package Structure
패키지를 분류하면 아래의 6가지 패키지 분류로 나누어 진다. 패키지 분류와 속하는 패키지 명이다.
– Registry (config)
– Controller (controller)
– Service (service, vo)
– Domain (domain)
– Repository (repository, dto)
– External (external)
-
controller
– 컨트롤러 클래스들이 위치한다. 컨트롤러 클래스는 Http, Grpc 프로토콜 구현체가 포함된다
– 메뉴 별로 category depth를 추가해서 관리한다. (ex: protocol.merchant, potocol.partner)
-
vo : Controller와 Service간의 데이터 전송을 위해서 사용되는 클래스들이 정의된다.
-
protocol
– service 클래스에 전달할 Value 클래스들을 정의한다. Request 클래스는 엔드포인트당한개씩 존재한다. (추천 Naming: ~Request)
– service 클래스에서 return할 Value 클래스들을 정의한다. Response 클래스는 엔드포인트당한개씩 존재한다. (추천 Naming: ~Response)
– 메뉴 별로 category depth를 추가해서 관리한다. (ex: protocol.merchant, potocol.partner)
– Request 클래스는 toParam(), Response 클래스는 ofResult(…) method를 정의해서 converter와 presenter 역할을 수행하게 한다.
-
model
– protocol 클래스에서 멤버 변수로 사용되고 있는 Value 클래스를 정의한다.
– 메뉴 별로 category depth를 추가해서 관리한다. (ex: protocol.merchant, potocol.partner)
– toDto()또는 ofDto(…) method를 정의해서 converter또는 presenter 역할을 수행한다.
– dto.model 또는 dto.common 클래스들과 이름이 겹칠 수 있으므로 ~Vo로 네이밍 한다.
-
common
– 공통으로 사용되는 Value 클래스, 추가 category depth 없이 관리한다.
– toDto()또는 ofDto(…) method를 정의해서 converter또는 presenter 역할을 수행한다.
– dto.model 또는 dto.common 클래스들과 이름이 겹칠 수 있으므로 ~Vo로 네이밍 한다.
-
-
service
– domain, repository, external등의 패키지들을 이용해서 서비스 로직 클래스들을 작성한다.
– 메뉴 별로 category depth를 추가해서 관리한다. (ex: protocol.merchant, potocol.partner)
-
dto
-
protocol
– repository 인터페이스에 pass할 파라미터 Value 클래스들을 정의한다. (추천 Naming: ~Param)
– repository 인터페이스에서 return할 모델 Value 클래스들을 정의한다. (추천 Naming: ~Result)
– 도메인 별로 category depth를 추가해서 관리한다. (ex: dto.payment, dto.cashreceipt)
-
model
– protocol 클래스에서 멤버 변수로 사용되고 있는 Value 클래스를 정의한다.
– 패키지내 클래스가 15 이상으로 많아지면 category depth(ex: dto.payment, dto.cashreceipt)를 추가해서 분류해서 관리한다.
– vo.model 또는 vo.common 클래스들과 이름이 겹칠 수 있으므로 ~Dto로 네이밍 한다.
– 도메인 별로 category depth를 추가해서 관리한다. (ex: dto.payment, dto.cashreceipt)
-
common
– 공통으로 사용되는 Value 클래스, 추가 category depth 없이 관리한다.
– vo.model 또는 vo.common 클래스들과 이름이 겹칠 수 있으므로 ~Dto로 네이밍 한다.
– 도메인 별로 category depth를 추가해서 관리한다. (ex: dto.payment, dto.cashreceipt)
-
-
repository
– 데이터를 핸들링 하기 위한 CRUD 인터페이스들을 정의한다.
– CRUD 메소드 Naming은 각 각 (Create, Get, Put, Delete)를 Prefix로 가진다.
– dto 패키지의 파라미터 Value 클래스, 모델 Value 클래스들을 이용해서 Method들을 정의한다.
-
entity : DB에서 import한 entity모델들이 정의된다. PG에서는 JPA의
ddl-auto: none옵션을 기본으로 사용한다. 따라서 entity에 코드로 action 메소드를 정의 할 수 없기 때문에 entity는 도메인이 될 수 없다.
-
domain : 도메인 클래스들이 정의된다. 도메인 클래스는 서비스의 핵심 로직을 구현한 클래스이다.
-
config : 환경정보를 불러와서 서비스 동작 방식을 결정짓는 클래스들을 정의한다. 이러한 형태의 클래스들은 Spring Config 클래스들이 포함된다.
-
external – 외부 패키지, 서비스들의 인터페이스, concrete 클래스들이 정의된다. – 패키지, 서비스 별로 category depth를 추가해서 관리한다. (ex: external.otpgenerator, dto.paymentproxy)
Naming
-
Package
- 소문자만 사용
- ‘-’ 또는 ‘_’ 사용하지 않기
- GoodCase
package com.example.deepspace;
-
File Naming
- JAVA는 파일 이름이 기본적으로 top-level 클래스 명을 따른다.
-
Class, AbstractClass
- 파스칼 케이스(PascalCase)를 따른다.
- GoodCase
public class PaymentService { ... }
-
Interface
- 파스칼 케이스(PascalCase)를 따른다.
- 인터페이스 네이밍 앞에 prefix I를 붙인다.
- GoodCase
public interface IPaymentService { ... }
-
Method
- 카멜 케이스(carmelCase)를 따른다.
- GoodCase
public interface IPaymentService { void paymentCredit(Payment payment); }
-
Member, Local Variable
- 카멜 케이스(carmelCase)를 따른다.
- GoodCase
public class PaymentService { private int orderCount; public void printLocalCount() { int orderCountLocal = 0; ... } }
-
Constant
- 대문자(UPPERCASE)와 함께 ‘_‘을 구분자로 사용한다.
- public static final과 함께 사용하도록 한다.
- GoodCase
public class PaymentService { public static final int PAYMENT_METHOD = 1; }
Style
- Indentation
- tab(’\t’, 0x09)을 사용하지 말라
- 4개의 whitespace(’ ‘, 0x20)로 사용해
- GoodCase
public class PaymentService { public void func(){ System.out.println("expression after indentation of 8 whitespaces"); } }
Rules Must Obey
-
(Do) 공백, 문자열이 포함된 Column의 사이즈를 120로 제한
- 예외사항
- 열 제한을 지 킬 수 없는 행 (ex: 긴 URL 주소)
- 예외사항
-
(Do) 값이 정확해야 하는 부동소수점 사칙연산에는 numeric 타입 (java.math.BigDecimal)을 이용해라
-
(Don’t)