DTO vs VO vs Entity

jione ·2022년 12월 4일
6

DTO

DTOData Transfer Object로 계층(Layer)간 데이터 교환을 위해 사용하는 객체다.

여기서 계층은 View, Controller, Service, Repository 등을 의미한다. 데이터 교환을 위해서만 사용되기에 로직은 갖고 있지 않고 데이터를 담고 꺼내는 getter/setter 메소드만 갖는다. DTO는 데이터를 전송할 때 사용되는 바구니라고 생각하면 좋다.

  • DTO 예제 코드

    class MoveDto {
        private String source;
        private String target;
    
        public MoveDto(int rend, int green, int blue) {
            this.source = source;
            this.target = target;
        }
    
        public String getSource() {
            return source;
        }
    
        public String getTarget() {
            return target;
        }
    
        public void setSource(String source) {
            this.source = source;
        }
    
        public void setTarget(String target) {
            this.target = target;
        }
    }

VO

VOValue Object로 값 그 자체를 표현하는 객체이다.

서로 다른 이름을 갖는 VO 인스턴스라도 모든 속성 값이 같다면 두 인스턴스는 같은 객체라고 할 수 있다. 이를 위해 VO는 equals()와 map 등에서 hashCode로 값을 찾기 위해 hashCode()를 필수적으로 오버라이딩 해야한다. 따라서 VO의 모든 속성 값이 같다면 같은 객체이다의 전제 조건은 equals()와 hashCode()를 오버라이딩하는 것이다.
VO는 객체의 불변성을 보장하며 DTO와 달리 로직을 포함할 수 있다. 또한 DTO와 다르게 VO는 값 그 자체의 의미를 가진 불변 클래스(Read-Only)를 의미한다. DTO는 인스턴스 개념이라면 VO는 리터럴 개념이라고 할 수 있다.

DTO vs VO

  • DTO는 Layer간의 통신 용도로 오고가는 객체이다.
  • VO는 특정한 값을 나타내는 객체이다.
  • 웹 개발에서 혼용해서 쓰는 VO는 사실 DTO다.

Entity

Entity는 실제 DB 테이블과 매핑되는 클래스이다.

속성 값으로 구분되는 VO와 달리 Entity는 ID로 구분된다. 로직을 포함할 수 있다. Entity는 JPA에서 사용하는 객체이므로 JPA 외에서 사용하지 않는 것을 권장한다.

  • Entity 예제

    @Table("user_info")
    public class UserInfo {
    
        @Id
        private Long id;
        private String name;
        private String email;
    
        public UserInfo() {}
    
        public UserInfo(String name, String email) {
            this.name = name;
            this.email = email;
        }
    
        public Long getId() { return this.id; }
    
        public String getName() { return this.name; }
    
        public String getEmail() { return this.email; }
    }

Entity를 DTO 대신에 사용할 수 있을까?

사용할 수는 있다. 그러나 View에서 요청하는 속성 값들이 요청에 따라 계속 달라질 수가 있는데, Entity를 사용하게 되면 영속성 모델을 표현한 Entity 자체의 값의 순수성이 모호하기 때문에 Controller에서 사용할 DTO와 Entity 클래스는 분리하는게 좋다. 또한, Entity 객체를 영속 계층 바깥쪽에서 사용하는 방식보다는 DTO를 사용하는게 좋다.

Client <--DTO--> Controller <--DTO--> Service <-- DTO --> Repository <-- Domain (Entity) --> DB

순수하게 데이터를 담고 있다는 점에선 DTO와 Entity 객체가 유사하지만 DTO는 목적 자체가 데이터의 전달이라 읽고, 쓰는 것이 모두 허용되어 일회성으로 사용되는 성격이 강하다. JPA를 이용하게 되면 Entity 객체는 단순히 데이터를 담는 객체라기 보단 실제 데이터베이스와 관련이 있고, 내부적으로 EM(Entity Manager)이 관리하는 객체다. 생명주기도 다르기 때문에 분리하여 처리한다.

정리

DTOVOEntity
용도Layer간의 데이터 전송의미있는 값을 표현DB 테이블과 매핑되는 클래스
가변/불변가변 객체(Mutable Object)를 생성 후 상태를 변경할 수 있다.불변 객체(Immutablel Object) 생성 후 상태 변경이 없다.가변 객체(Mutable Object)를 생성 후 상태를 변경할 수 있다.
로직 포함 여부NYY

참고

profile
Software Engineer 🐣

1개의 댓글

comment-user-thumbnail
2022년 12월 14일

That's great. I was impressed by your writing. I am happy to see such a topic. Please come to my blog and read it.

https://www.scoresense.me/

답글 달기