이전 포스팅에서 도메인에 대해 다루며 Entity와 VO에 대해 짤막하게 소개했습니다.
이번 포스팅에서는 Entity와 VO의 특징과 차이점에 대해 서술해보겠습니다.
Entity
💡변별할 수 있는 사물 (Peter Chen, 1976)
💡정보를 저장할 수 있는 어떤것 (James Martin, 1989)
💡정보를 저장할 수 있는 사람, 장소, 물건, 사건 그리고 개념 등(Thomas Bruce, 1992)
쉽게 얘기하면 데이터를 저장하고 관리하기 위한 객체입니다.
다음과 같은 특징을 지니고 있습니다.
1. 실제 DB테이블과 매핑되는 핵심 객체
DB의 테이블과 1:1로 매핑되므로, 테이블에 없는 컬럼이 필드에 있어서는 안됩니다.
또한, Entity를 기준으로 테이블이 생성되고 스키마가 변경되기 때문에,
응답 및 요청의 전달을 위한 클래스로 사용해서는 안됩니다.
2. 비즈니스 로직을 포함할 수 있다.
Entity는 getter/setter외에도 비즈니스로직을 포함 할 수 있습니다.
대신 Entity를 자료구조로 사용할지, 객체로 사용할지에 따라서 비즈니스로직의 확장여부는 달라져야 합니다.
- 자료구조로 사용할 구체적인 Point Class
public class Point{
public double x;
public double y;
}
- 객체로 사용될 추상적인 PointClass
public interface Ponint{
double getX();
double getY();
double getR();
double getTheta();
void setCartesian(double x, double y);
void setPolar(double r, double theta);
}
4. Identifier(식별자)로 구분된다.
Identifier(이하 ID)는 동일성을 지켜주는 속성입니다.
주민등록번호도 ID의 예시로 들 수 있겠습니다.
제가 이사를 해 주소지가 바뀌던, 결혼을 하던, 외양이 크게 바뀌었던간에 주민등록번호로는 저를 식별할수 있죠.
5. DDD
이렇듯 Entity를 객체로 사용하게 되면 서비스단에서 구현할 비즈니스로직이 대부분 Entity에 위치하게 됩니다. 그럼 서비스단에서는 Entity를 호출하는 역할만으로도 구성될 수 있게 됩니다. 이게 바로 DDD패턴입니다.
6. JAP의 Entity?
아키텍처 관점에서 데이터베이스는 엔티티가 아니다.
왜냐하면, 데이터베이스는 세부사항이기 떄문에 아키텍처의 구성요소 수준으로 구현될 수 없다.
소프트웨어 시스템의 아키텍처가 건물의 설계라면, 데이터베이스는 건물의 문 손잡이의 관계와 같다.
- 클린 아키텍쳐
데이터베이스는 DDD의 Entity가 아니며, ORM의 JPA도 마찬가지이므로, 용어도 같고 개념도 비슷하지만 혼동하먄 안되겠습니다. Entity와 JPA의 Entity는 다른 개념입니다.
VO
💡값 그 자체인 객체
도메인에서 한 개 또는 그 이상의 속성들을 묶어서 특정 값을 나타내는 객체입니다.
다음과 같은 특징을 지니고 있습니다.
1. 비즈니스 로직을 포함할 수 있습니다.
하지만 setter는 구현을 지양해야 합니다.
동등성 개념때문에 그렇습니다. 이는 3번에서 설명하겠습니다.
2. 모든 속성값이 같다면 같은 객체로 취급합니다. (동등성)
VO는 주소지가 달라도, 보유하고있는 속성값이 같다면 같은객체로 취급합니다.
이를 위해서 Object로부터 상속받은 equals(), hashCode()메서드를 오버라이드 해야 합니다.
3 .불변성 보장을 위해 생성자 사용이 권장됩니다..
식별자가 없어서 값이 바뀌면 어떤 객체였는지 구분을 할 수 없습니다.
따라서, setter의 구현은 배제하고 생성자를 사용해 불변객체로써 사용해야 합니다.
- 간단한 VO Class
public class Money{
private final String value;
public Money(int value) {
this.value = value;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Money money = (Money) o;
return Objects.equals(value, carVO.value);
}
@Override
public int hashCode() {
return Objects.hash(value);
}
}
DTO
1. VO가 값 객체 그 자체라면, DTO는 계층간 데이터를 전달하기 위한 객체입니다.
2. 주로 view-contorller간 데이터 전달을 위해 사용됩니다.
3. 비즈니스 로직을 포함할 수 있으나, 보통은 getter-setter 구성으로 단순하게 사용합니다.
정리
간단하게 표로 정리해서 마무리하겠습니다.
분류 | Entity | VO | DTO |
용도 | DB 테이블 매핑 | 값 표현용 | 계층간 데이터 전송용 |
불변성 | 가변 또는 불변 | 불변 | 가변 또는 불변 |
로직 포함여부 | 포함 | 포함 | 포함 |
참고
클린 코드
클린 아키텍쳐
https://tecoble.techcourse.co.kr/post/2021-05-16-dto-vs-vo-vs-entity/
https://tecoble.techcourse.co.kr/post/2020-06-11-value-object/
https://velog.io/@jay/%EC%89%BD%EA%B2%8C-%EB%A7%90%ED%95%98%EB%8A%94-DDD-%EC%97%94%ED%8B%B0%ED%8B%B0
https://namocom.tistory.com/980