엔티티와 벨류 제대로 구분해야 도메인을 올바르게 설계하고 구현할 수 있기 때문에 이 둘의 차이를 명확하게 이해하는 것은 도메인을 구현하는 데 있어서 중요하다.
엔티티.
- 엔티티의 가장 큰 특징은 식별자를 가진다.
- 식별자는 엔티티 객체마다 고유해서 각 엔티티는 서로 다른 식별자를 갖는다.
- 엔티티의 식별자는 바뀌지 않고 고유하기 때문에 두 엔티티 객체의 식별자가 같으면 두 엔티티는 같다고 판단할 수 있다.
엔티티의 식별자 생성
- 특정 규칙에 따라 생성
- UUID나 Nano ID와 같은 고유 식별자 생성기 사용
- 값을 직접 입력
- 일련번호 사용(시퀀스나 DB의 자동 증가 컬럼 사용)
벨류
도메인 모델에 set 메서드 넣지 않기
- 도메인 모델에 get/set 메서드를 무조건 추가하는 것은 좋지 않은 버릇이다. 특히 set 메서드는 도메인의 핵심 개념이나 의도를 코드에서 사라지게 한다.
- 무조건 적인 set 메서드는 지양하고, 특정 행위의 의미를 파악할 수 있는 메서드를 제공하자.
- ex) 주문 취소 처리
public class Order {
private OrderState state;
private void verifyNotYetShipped() {
if (this.state != OrderState.PAYMENT_WAITING && this.state != OrderState.PREPARING) {
throw new IllegalStateException("이미 배송이 시작 되었습니다.");
}
}
public void cancleOrder() {
verifyNotYetShipped();
this.state = OrderState.CANCELED;
}
// setter를 사용하면 단순히 주문 상태 값을 설정한다는 것으로 밖에 이해할 수 없다.
public void setOrderState(OrderState state) {
this.state = state;
}
}
- 불변 밸류 타입을 사용하면 set 메서드를 구현하지 않는다.
- set 메서드를 제공하면 데이터가 변경될 수 있음.
DTO의 get/set 메서드
- DTO는 Data Transfer Object의 약자로 프레젠테이션 계층과 도메인 계층이 데이터를 서로 주고받을 때 사용하는 일종의 구조체이다.
- DTO가 도메인 로직을 담고 있지는 않기에 get/set 메서드를 제공해도 도메인 객체의 데이터 일관성에 영향을 줄 가능성이 높지 않다.
- 요즘 개발 프레임워크나 개발 도구는 set 메서드가 아닌 private 필드에 직접 값을 할당할 수 있는 기능을 제공하고 있어 set 메서드가 없어도 프레임워크를 이용해서 데이터를 전달받을 수 있다.
- DTO도 불변 객체로 두어 불변의 장점을 DTO까지 확장할 수 있다.
- 메시지 컨버터