면접대비

DTO와 VO 이야기(feat. Entity)

코딩하는흑구 2021. 3. 31. 00:39

이번 주제는 DTO와 VO에 관한 이야기이다.

 

흔히 다들 DTO와 VO를 같은 의미로 사용하고있고 같은 역할로 사용하고 있다고 판단한다.

 

사실 그럴것이 지금 개발상태에서는 두가지 사용법이 혼용되고 있기때문이다. 하지만 명백히 DTO와 VO는 그 히스토리가 다르며 구성요소와 사용법도 다르다.

 

오늘은 그것에 대해서 정리해보고자 한다.

 


VO( value object )

일단 VO의 경우는 예전으로 거슬러 올라가면 EJB라는 프레임워크를 사용할 때 값을 가지는 객체에서 유래한다. 안에 있는 내용물은 값 자체를 의미하고 내부 메소드를 통해 비즈니스를 가지거나 한다.

 

내용물이 값 자체를 의미하기 때문에 read only 특징을 가지고 있다.

 

또한 값 자체를 의미하기 때문에 같은 객체라는 것을 보장하기 위해서는 equals와 hashcode를 재정의해주어야한다. VO 객체의 두 메소드를 재정의해야하는 이유는 아래의 링크에 서술되어있다.

sas-study.tistory.com/402

equals 메소드와 hashCode 메소드 재정의는 언제해야할까?

equals 메소드 우리는 흔히 equals 는 값비교, == 는 주소값 비교라고 한다. 왜 equals는 값비교일까? 기본적으로 자바의 모든 클래스들은 Object 클래스를 상속하게 된다. 즉, 모든 클래스는 Object 클래

sas-study.tistory.com

 

DTO( data transfer object )

DTO는 레이어간 데이터를 전송하기 위해 정의된 객체이다. 주로 json serialization과 같은 직렬화에 사용되는 객체이다. DTO는 원래 DAO( data access object )패턴에서 유래된 단어로 DAO에서 DB처리 로직을 숨기고 DTO라는 결과값을 내보내는 용도로 활용했었다.

 

흔히 자바빈이라는 객체처럼 Getter/Setter만을 가지며 비즈니스를 포함하지 않는다고 한다. 단지 데이터를 전송하기 위한 역할로 setter 또한 초기화시에 사용되는 역할을 위해 선언할 뿐이다. 최근에는 static of() 메소드 같은 팩토리 메소드 패턴으로 setter를 대체해서 초기화하기도 하는 것 같다.

 

 

공통점과 차이점

 

두 객체는 일단 값을 가진다는 객체의 기본적인 공통점이 있지만, 값자체에 의미가 있는 VO전달될 데이터를 보존해야하는 DTO의 특성상 개념의 차이가 매우 다르다.

 

또한 VO컬럼 값들에 대해 read-only를 보장해줘야만 존재자체의 신뢰성이 확보되지만 DTO의 경우는 단지 데이터를 담는 그릇의 역할일 뿐 값은 그저 전달되어져야할 대상일 뿐이다.

 


Entity

데이터베이스 테이블과 같다고 생각하면 될것같다. 물론 완전히 같다는 것은 아니지만 주로 데이터베이스 persistent의 목적으로 사용되는 객체이다.

 

entity 객체는 DB Layer와 많이 밀접한 객체라서 Setter 접근을 금지하고 기본생성자 사용을 제한(protected)해 일관성을 유지해야한다. entity의 값이 변경될 여지가 발생하여 영속성 영역에서 얻어진 신뢰성있는 값들이 훼손될 여지가 존재한다.

 

이는 JPA를 활용해보면 Entity에 대해서 좀더 많이 와닿을 수 있을 것 같다.

 


 

현재는 재직중인 회사에서 특정 객체가 위의 예에 딱 들어맞는 부분이 별로 없어서 정의하기가 약간 애매모호해졌다. 물론 저러한 용어의 정의와 규칙들을 모두 지키면서 개발하는 개발자들도 존재하겠지만 언제까지나 딱 들어맞는 개발방법들만이 선택되지는 않을 것이기 때문에 내부적인 팀원들과 소통하여 자유도를 줄수있는 결정을 할 때가 있을지도 모르겠다.

 

내가 재직중인 회사에서는 DTO, VO, Entity로 나누지않고 객체가 역할을 하는 위치에서 나누고 있다. 예를 들어, Request Parameter or Body에서 Controller로 바인딩되는 객체들을 Param 객체로 정의하고, DB Layer에서 select로 조회한 객체들을 Entity로 정의하고, Entity 객체를 Response Body로 반환할 Result 객체로 매핑하여 사용하고 있다.

 

따라서 DTO와 VO의 특징이 어느정도 섞여진 새로운 타입들을 팀내에서 정의하였고, 그 정의를 기반으로 동작하기 때문에 DTO와 VO의 기본원칙을 strict하게 고수하지 않아도 충분히 개발은 가능하다.

 

하지만 역설적이게도 기회가 된다면 이러한 원칙을 strict하게 지키는 개발도 경험해보고 싶기도 하다.