DTO
는Data Transfer Object
로 계층(Layer)간 데이터 교환을 위해 사용하는 객체다.
여기서 계층은 View, Controller, Service, Repository 등을 의미한다. 데이터 교환을 위해서만 사용되기에 로직은 갖고 있지 않고 데이터를 담고 꺼내는 getter/setter 메소드만 갖는다. DTO는 데이터를 전송할 때 사용되는 바구니라고 생각하면 좋다.
DTO 예제 코드
class MoveDto {
private String source;
private String target;
public MoveDto(int rend, int green, int blue) {
this.source = source;
this.target = target;
}
public String getSource() {
return source;
}
public String getTarget() {
return target;
}
public void setSource(String source) {
this.source = source;
}
public void setTarget(String target) {
this.target = target;
}
}
VO
는Value Object
로 값 그 자체를 표현하는 객체이다.
서로 다른 이름을 갖는 VO 인스턴스라도 모든 속성 값이 같다면 두 인스턴스는 같은 객체라고 할 수 있다. 이를 위해 VO는 equals()
와 map 등에서 hashCode로 값을 찾기 위해 hashCode()
를 필수적으로 오버라이딩 해야한다. 따라서 VO의 모든 속성 값이 같다면 같은 객체이다의 전제 조건은 equals()와 hashCode()를 오버라이딩하는 것이다.
VO는 객체의 불변성을 보장하며 DTO와 달리 로직을 포함할 수 있다. 또한 DTO와 다르게 VO는 값 그 자체의 의미를 가진 불변 클래스(Read-Only)
를 의미한다. DTO는 인스턴스 개념이라면 VO는 리터럴 개념이라고 할 수 있다.
DTO
는 Layer간의 통신 용도로 오고가는 객체이다.VO
는 특정한 값을 나타내는 객체이다.
Entity
는 실제 DB 테이블과 매핑되는 클래스이다.
속성 값으로 구분되는 VO와 달리 Entity는 ID로 구분된다. 로직을 포함할 수 있다. Entity는 JPA에서 사용하는 객체이므로 JPA 외에서 사용하지 않는 것을 권장한다.
Entity 예제
@Table("user_info")
public class UserInfo {
@Id
private Long id;
private String name;
private String email;
public UserInfo() {}
public UserInfo(String name, String email) {
this.name = name;
this.email = email;
}
public Long getId() { return this.id; }
public String getName() { return this.name; }
public String getEmail() { return this.email; }
}
사용할 수는 있다. 그러나 View에서 요청하는 속성 값들이 요청에 따라 계속 달라질 수가 있는데, Entity를 사용하게 되면 영속성 모델을 표현한 Entity 자체의 값의 순수성이 모호하기 때문에 Controller에서 사용할 DTO와 Entity 클래스는 분리하는게 좋다. 또한, Entity 객체를 영속 계층 바깥쪽에서 사용하는 방식보다는 DTO를 사용하는게 좋다.
Client <--DTO--> Controller <--DTO--> Service <-- DTO --> Repository <-- Domain (Entity) --> DB
순수하게 데이터를 담고 있다는 점에선 DTO와 Entity 객체가 유사하지만 DTO는 목적 자체가 데이터의 전달이라 읽고, 쓰는 것이 모두 허용되어 일회성으로 사용되는 성격이 강하다. JPA를 이용하게 되면 Entity 객체는 단순히 데이터를 담는 객체라기 보단 실제 데이터베이스와 관련이 있고, 내부적으로 EM(Entity Manager)이 관리하는 객체다. 생명주기도 다르기 때문에 분리하여 처리한다.
DTO | VO | Entity | |
---|---|---|---|
용도 | Layer간의 데이터 전송 | 의미있는 값을 표현 | DB 테이블과 매핑되는 클래스 |
가변/불변 | 가변 객체(Mutable Object)를 생성 후 상태를 변경할 수 있다. | 불변 객체(Immutablel Object) 생성 후 상태 변경이 없다. | 가변 객체(Mutable Object)를 생성 후 상태를 변경할 수 있다. |
로직 포함 여부 | N | Y | Y |
That's great. I was impressed by your writing. I am happy to see such a topic. Please come to my blog and read it.
https://www.scoresense.me/