logo

Dto와 Vo

DtoVo를 비교해보자.

  • Dto : 레이어 간에 데이터 전송을 위한 객체
  • Vo : 값 자체로 의미를 가지는 객체

구글링을하면,
DtoVo 의 차이를 read-only 속성으로 정의한다.
하지만, 그 차이를, 그 용도를 명확히 이해하지 못했다.

유투브의 우아한테크에 이 차이점을 비교한 발표영상을 발견했다!

5분의 짧은 영상이지만, 둘의 차이점을 이해하기에는 부족함이 없었다.

<br>

Dto (레이어 간에 데이터 전송을 위한 객체)

DtoData Transfer Object의 약자이며,
레이어간에 데이터를 전송하기 위한 객체이다.

A에서 B로 보낼때 X는 모양의 데이터가 필요하고,
X 모양을 Dto로 정의한 것이다.

그럼 둘 사이를 전달하기 위해서 우리는 무슨 행위를 필요로할까?

Dto의 내용에 접근하는 get의 행위를 필요로 할 것이다.
필요하다면, 정렬, 직렬화와 같은 데이터를 표현하기 위한 기능을 가질 수 도 있을 것이다.

<br>

Vo (값 자체로 의미를 가지는 객체)

VoValue Object의 약자이며,
값 자체로 의미를 가지는 객체이다.

이 개념을 이해하기 어려웠는데,
값 자체로 의미를 가진다는 것은 무슨의미일까?

식별자가 곧 을 의미하는 것이다.

Integer v1 = 10을 정의했을 때,
v110이라는 값이 식별자가 되며, 값 자체로서의 의미를 가진다.

Integer v2 = 20을 정의했을 때,
v220이라는 값이 식별자가 되며, 값 자체로서의 의미를 가진다.

하지만 어떤 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이라고 선언하다.

v1v2는 동일한가?
v1 == v2true일까?

Integer는 값 자체가 식별자이다.
따라서, 명백히 같은 값을 가지므로 동일하다고 할 수 있으며,
결과는 true일 것이다.

하지만, A객체를 보자.
선언된 A a1 = new A(10), A a2 = new A(10)은 동일한가?
a1 == a2true일까?

그렇지 않다, 객체는 주소라는 식별자를 가지고 있고,
a1a2는 명백히 다른 주소값을 가지고 있는 다른 객체이며, 다른 이다.

하지만 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>

저는 이렇게 사용하고 있습니다 :

정답은 아니지만, 저는 이렇게 사용해보고 있습니다 : )

<br>

forntend에서 backend와의 통신과 같이
또는 서버내에서 타서버Api를 같이,
다른외부와의 통신 사이에는 dto를 정의해서 사용합니다.

ex) requestDto, responseDto

<br>

반대로, 서버내에서, 여러 객체의 이해관계간에
예를 들어 Aclass에서 Bclass간의 데이터를 전달한다면,
vo를 정의해서 사용합니다.
필요하다면 vo에 비즈니스 로직을 정의합니다.

ex)

ImageSizeVo imageSizeVo  = new ImageSizeVo(width, height);
int area = imageSizeVo.getArea();
CommentCount 0
이전 댓글 보기
등록
TOP