DTO, VO 비교 + Entity (2022. 08. 26 추가)
DTO 와 VO 비교
DTO : Data Transfer Object
VO : Value Object
DTO
Data Transfer Object
Transfer : 옮기다, 이송하다
DTO는 레이어 간 데이터를 이송하기 위한 객체이다.
따라서 다른 로직이 포함되지 않고 데이터 접근, 수정 메서드인 getter, setter 메서드만 존재한다.
setter의 경우 데이터가 의도치 않게 변조될 가능성이 있어 Builder 패턴 또는 생성자를 이용하여 생성해주기도 한다.
VO
Value Object
VO는 그저 값을 담는 객체이다.
DTO 와 다르게 다른 로직이 포함될 수 있으며, 불변성이 '보장'되어야한다.
그리고 객체의 속성 값이 모두 같다면 같은 객체로 본다.
* equals() 메서드와 hashcode() 를 오버라이드 해주어야함.
활용
DTO 는 레이어 간 데이터 이동시 사용하면 될것 같다.
VO 는 엔티티에서 나이, 몸무게, 주소 같은 타입들을 강타입으로 선언해주기 위해 검증 메서드를 포함하여 사용하는 것으로 먼저 정리해보겠다.
예시
변경 전
public class Person {
private int age;
private String address;
// ...
}
변경 후
public class Age {
private int age;
public Age(int age) {
this.age = age;
// 검증
}
// ...
}
public class Address {
private String address;
public Address(String address) {
this.address = address;
// 검증
}
// ...
}
Age, Address 가 VO
public class Person {
private Age age;
private Address address;
// ...
}
이 부분은 DDD (Domain-Driven-Design) 에서 엔티티 도메인 등 좀 더 심화적으로 공부해 볼 필요가 있다.
(2022. 08. 26 추가)
+ ORM 세분성
VO와 Entity의 차이 중 하나는 객체 비교다.
개발자 입장에서 Entity는 PK값이 같다면 같은 객체로 판단한다. VO는 값이 하나라도 다르면 다른 객체로 본다.
Person Entity안의 address를 따로 Address라는 객체로 분리할 때,
ex 1)
@Embeddable
public class Address {
private String city;
private String streat;
}
@Entity
public Person {
@Id
@GEneratedValue(...)
private Long id;
// ...
@Embedded
private Address address;
}
이 때, Address 객체는 VO 객체로 봐야겠다.
address의 city, streat 값이 같다면 같은 객체로 봐야 맞을 것같다.
하지만, 다른 테이블로 저장하고 연관관계를 맺는 경우라면?
ex 2)
@Entity
public class Address {
@Id
@GeneratedValue(...)
private Long id;
private String city;
private String streat;
}
@Entity
public Person {
@Id
@GeneratedValue(...)
private Long id;
// ...
@OneToOne
@JoinColumn(name = "address_id")
private Address address;
}
Address는 Entity다. 따라서 city, streat값이 같아도 id값이 다르면 다른 객체이다.
id값이 같고 city, streat 값이 다를 때 같은 객체의 값이 달라진것으로 판단한다.
즉, 값이 다르면 다른 객체로 보는 VO가 아닌것이다.
단순히 검증을 하고 강타입으로 제약하기 위함이라면 VO객체로, Embeddable로 사용하면 되겠다.
만약, 한 사람이 갖을 수 있는 주소지가 많아지면? Address를 Entity로 만들어 연관관계를 맺으면 되겠다.
이 때는 VO라고 볼 수 없을 것이다.