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);