DTO vs VO

taehee-kim-dev·2021년 2월 25일
0
post-thumbnail

우테코에서 DTO vs VO 에 대한 주제로 테코톡 발표를 했다.

발표를 마친 뒤 질의응답을 받는 시간에, 크루 루트 와 다른 크루들이 핵심적인 질문을 했다.

명쾌한 답변을 못 했다. 일단 나에게도 새로운 궁금증이 생겼으니 스스로도 답답했고, 꼭 짚고 넘어가고 싶었다.

또 명쾌한 해답을 듣지 못한 크루들한테 미안해, 추가적인 설명을 해 주고 싶었다.

아래의 내용은 내가 우테코 슬랙에 공유한 내용이다.

__ Q. VO가 getter/setter 메소드 외에 다른 비즈니스 로직들을 가질 수 있다고 했는데, 그러면 VO를 DTO로 쓸 수 있는 것 아닌가요? __

A. 네, VO도 DTO의 "기능" 을 할 수 있습니다. 코드만 그에 맞게 짜면 어느 형태의 객체를 사용해도 프로그램은 돌아갈 테니까요. DTO도 equals() 와 hashCode()만 오버라이딩하면 사실상 VO의 성질을 갖게 되죠. 아까 Entity를 DTO로 쓰지 말라고 했는데, 사실 목적만 달성할 수 있으면, Entity를 DTO로 사용해도 코드만 잘 짜면 프로그램이 돌아가긴 할 겁니다.

이 "혼용 가능성"의 문제 때문에, 많은 분들이 DTO와 VO를 혼동하시고 혼용하시는 거라고 생각합니다. 하지만 발표 초반에서도 말씀드렸듯이, "DTO와 VO는 이름이 다른 만큼, 구분해서 쓰는 게 좋을 것 같다." 가 제 생각입니다! 그리고 정의적 측면에서 DTO는 "데이터 전달용 객체", VO는 "값 자체 표현 객체"로 정의 자체가 다릅니다. 그래서 테코톡 주제에도 이 주제가 포함되어 있는게 아닐까 싶습니다.

DTO : View에서 요구하는 데이터들을 "최종적"으로 알맞게 담아 View에 넘겨주는 객체. -> 적절한 데이터들을 가져다가 조립하듯이 DTO에 알맞게 담아서 넘기면 된다.

VO : 값 그 자체. 그래서 불변. LottoNumber 처럼 도메인 자체가 될 수 있음. (사진 참고해주세요!) -> View에서 요구하는 데이터들 중에 VO가 포함되어있으면, VO를 바로 보내는 것 보다, DTO에 VO를 담아서 보내는 게 정의상 맞지 않을까요?

DTO는 단순히 데이터를 담아서 전달하고 받아서 꺼내는게 목적이기 때문에, getter/setter 외의 별도의 비즈니스 로직을 갖지 않는다.
(이해가 쉽도록 바꿔봤습니다. -> DTO로만 쓸거면 getter/setter 외의 비즈니스 로직은 필요없다.)

VO는 getter/setter 외에도 모든 비즈니스 로직을 가질 수 있다.
(이해가 쉽도록 바꿔봤습니다. -> 모든 필드값 동등에 따른 객체들의 동등의 여부가 중요하지, 비즈니스 로직은 있으나 없으나 상관없다. (setter 성격의 메소드 제외.))

라는게 제 생각입니다!

"가질 수 있다", "가질 수 없다"로 설명하지 말고, "필요없다", "상관없다" 등으로 설명할걸 그랬네요..

혼란을 드려 죄송합니다 ㅠㅠ

다시 정리해 보면,

DTO는 데이터 전달 만을 위한 객체라는 게 핵심 정의이다. 그렇기 때문에 완전히 데이터 전달 용도로만 사용하는게 목적이라면, getter/setter만 필요하지, 이외의 비즈니스 로직은 굳이 있을 필요가 없다.

VO는 두 객체의 모든 필드 값들이 동일하면 두 객체는 같다! 가 핵심 정의이다. 그렇기 때문에 완전히 값 자체 표현 용도로만 사용하는 게 목적이라면, 두 객체의 모든 필드 값들이 모두 같으면 같은 객체이도록 만드는 것(equals() 와 hashCode()의 오버라이딩)이 중요하지, 메소드는 어떤 메소드가 있든 말든 상관 없다.

단, setter 성격의 메소드는 없애고 불변 객체로 만들어야 한다. 왜냐하면 VO는 특정 값 자체를 표현하기 때문이다.

로또 미션에서, 각 로또 번호들을 VO로 만들어서 사용한다고 해 보자. LottoNumber(1번)의 객체를 불변으로 만들어야 "이 객체는 로또번호 1번 이다." 라고 할 수 있는 것이지, 중간에 1번이라는 숫자가 바뀔 수 있는 여지(setter 성격의 함수가 존재)가 있으면, "이 객체는 로또 번호 1번 그 자체 이다." 라고 할 수 없을 것이다. 정체성 자체(속성 값)가 계속 변할 가능성이 있기 때문에, "이 객체는 A라는 특정 값이다!" 라고 말할 수 없다.

profile
Web Back-End (Spring, JPA, AWS)

관심 있을 만한 포스트

0개의 댓글