DTO vs VO
Dto와 Vo
Dto와 Vo를 비교해보자.
Dto:레이어 간에 데이터 전송을 위한 객체Vo:값 자체로 의미를 가지는 객체
구글링을하면,
Dto와 Vo 의 차이를 read-only 속성으로 정의한다.
하지만, 그 차이를, 그 용도를 명확히 이해하지 못했다.
유투브의 우아한테크에 이 차이점을 비교한 발표영상을 발견했다!
5분의 짧은 영상이지만, 둘의 차이점을 이해하기에는 부족함이 없었다.
<br>
Dto (레이어 간에 데이터 전송을 위한 객체)
Dto는 Data Transfer Object의 약자이며,
레이어간에 데이터를 전송하기 위한 객체이다.
A에서 B로 보낼때 X는 모양의 데이터가 필요하고,
이 X 모양을 Dto로 정의한 것이다.
그럼 둘 사이를 전달하기 위해서 우리는 무슨 행위를 필요로할까?
Dto의 내용에 접근하는 get의 행위를 필요로 할 것이다.
필요하다면, 정렬, 직렬화와 같은 데이터를 표현하기 위한 기능을 가질 수 도 있을 것이다.
<br>
Vo (값 자체로 의미를 가지는 객체)
Vo는 Value Object의 약자이며,
값 자체로 의미를 가지는 객체이다.
이 개념을 이해하기 어려웠는데,
값 자체로 의미를 가진다는 것은 무슨의미일까?
식별자가 곧 값을 의미하는 것이다.
Integer v1 = 10을 정의했을 때,
v1는 10이라는 값이 식별자가 되며, 값 자체로서의 의미를 가진다.
Integer v2 = 20을 정의했을 때,
v2는 20이라는 값이 식별자가 되며, 값 자체로서의 의미를 가진다.
하지만 어떤 A객체를 정의하고
public class A{
Integer value;
A(Integer value){
this.value = value;
}
}
A a1 = new A(10)를 선언했을 때,
a1은 그 자체만으로 값을 의미하는 객체라고 할 수 있을까?
그렇지 않다, a1은 객체로 선언된 것이다.
a1자체는 주소값을 식별자로 가지고 있는 객체이다.
그럼 A객체가 값으로의 의미를 가질려면 어떻게해야할까?
<br>
첫째, 값 자체가 식별자여야 한다.
Integer v1 = 10, Integer v2 = 10이라고 선언하다.
v1과 v2는 동일한가?
v1 == v2는 true일까?
Integer는 값 자체가 식별자이다.
따라서, 명백히 같은 값을 가지므로 동일하다고 할 수 있으며,
결과는 true일 것이다.
하지만, A객체를 보자.
선언된 A a1 = new A(10), A a2 = new A(10)은 동일한가?
a1 == a2는 true일까?
그렇지 않다, 객체는 주소라는 식별자를 가지고 있고,
a1과 a2는 명백히 다른 주소값을 가지고 있는 다른 객체이며, 다른 값이다.
하지만 equals()와, hashCode() 메소드를 정의한다면,
논리적 동일함을 보장 할 수 있을 것이다.
그리고 값을 의미하기에 충분한 객체를 정의 할 수 있다.
class A{
int value;
public A(int value){
this.value = value;
}
@Override
public boolean equals(Object obj) {
A a2 = (A) obj;
return this.value == a2.value;
}
@Override
public int hashCode() {
return hash(this.value);
}
}
<br>
둘째, 불변해야 한다.
Integer v1 = 10인 값을, v1 = 20 바꾼다면, 값을 바꾼다 할 수 있다.
반대로, A a1 = new A(10)인 값을, a1.setValue(20)으로 바꾼다면,
동일한 a1이지만, 같은내용을 가지고 있지 않는다.
명백히 다른 내용을 가지게 할 수 있는 것이다.
따라서 내용이 바뀐다는 것은, 같은 값을 보장 할 수 없는 것이다.
값의 의미를 가지기에는 매우 불안정하다.
그러므로 Vo는 불변해야하는 값이어야 하며, 즉 read-only의 값이다.
따라서, Vo는 불변객체로 정의해야한다.
class A{
int value;
public A(int value){
this.value = value;
}
// 불변하자
public A add(A a2){
return new A(this.value + a2.getValue());
}
}
<br>
Dto vs Vo
둘의 차이점은 다음과 같다.
Dto, Vo는 레이어간의 데이터 전달에 사용 할 수있다.
다만, Vo는 불변객체이기 때문에, 모든 레이어간에도 데이터가 공유하다.
<br>
Dto는 값이 바뀔 수있으며,
new Dto(1) != new Dto(1)이다.
반대로, Vo는 불변해야하며,
new Vo(1) == new Vo(1)이다.
<br>
Dto는 단순히 데이터 접근이외의 기능을 가지지 않으며,
Vo는 비즈니스 로직을 포함 할 수 있다.
<br>
저는 이렇게 사용하고 있습니다 :
레이어간의 통신 사이에 필요하다면 dto를 정의해서 사용합니다.
ex) requestDto, responseDto
<br>
반대로, vo는 좀더 순수하게 사용합니다.
우리가 Integer를 사용하듯이, 어디서든 사용할 수 있는 객체를 vo로 사용합니다.
예를들어 Money라는 vo를 정의 할 수 도 있습니다.
그리고 Money라는 vo는 순수하며, 다른 레이어를 의존하지 않습니다.
그래서 어디서든지 Money를 마치 우리가 Integer를 사용하는 것처럼 사용 할 수있도록 합니다.
ex)
Money money = new money(1000);