슬기로운 개발생활

DTO와 VO 그리고 Entity 차이점 알아보기

by coco3o
반응형

Entity 란?

Entity 클래스는 실제 DataBase의 테이블과 1 : 1로 매핑되는 클래스로,
DB의 테이블내에 존재하는 컬럼만을 속성(필드)으로 가져야 합니다.
Entity 클래스는 상속을 받거나 구현체여서는 안되며, 테이블내에 존재하지 않는 컬럼을 가져서도 안됩니다.

이러한 Entity 클래스는 가장 Core한 클래스라고 부릅니다.

최대한 외부에서 Entity 클래스의 getter method를 사용하지 않도록 해당 클래스 안에서필요한 로직 method를 구현해야하고, Domain Logic만을 가지며, Presentation Logic을 가지고 있어서는 안됩니다.

Entity, DTO 클래스를 분리하는 이유

Entity와 DTO를 분리해서 관리해야 하는 이유는 DB 와 View 사이의 역할을 철저히 분리하기 위해서 입니다.

Entity 클래스는 실제 테이블과 매핑되어 만일 변경되게 된다면 다른 클래스에 영향을 끼치고,
DTO 클래스는 View와 통신하며 자주 변경되므로 분리 해주어야 합니다. (Entity 클래스 보호)

DTO는 Domain Model의 순수성을 지키기 위해 DTO는 Domain Model 객체를 그대로 두고 복사하여
다양한 Presentation Logic을 추가한 정도로 사용하며,

  • DTO === copy(Domain Model) + Persentation Logic

Domain Model 객체는 Persistent만을 위해서 사용해야합니다.


DTO (Data Transfer Object)

DTO(Data Transfer Object)는 데이터 전송(이동) 객체라는 의미를 가지고 있습니다.
DTO는 주로 비동기 처리를 할 때 사용합니다.

DTO는 각 계층(Layer)간 데이터 교환을 위한 객체(Java Beans)입니다.
(ex. View <-(DTO) -> Controller <- (DTO) -> Service )
로직을 갖고 있지 않는 순수한 데이터 객체이며, getter/setter 메소드만을 갖습니다.

public class PersonDTO {

    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

위의 클래스를 보면 getter/setter 가 존재합니다.
여기서 중요한건 Property(프로퍼티) 개념인데, 자바는 Property가 문법적으로 제공되지 않습니다.

자바에서 프로퍼티라는 개념을 사용하기 위해 지켜야 할 약속이 있습니다.
setter/getter 에서 set과 get 이후에 나오는 단어가 property라고 약속하는 것입니다.
그래서 위 클래스에서 프로퍼티는 name과 age 입니다.
중요한 것은 프로퍼티가 멤버변수 name, age로 결정되는 것이 아닌 getter/setter에서의 name과 age임을 명심해야 합니다.
즉 멤버변수는 아무렇게 지어도 영향이 없고 getter/setter 로 프로퍼티(데이터)를 표현한다는 것입니다.

자바는 다양한 프레임워크에서 데이터 자동화처리를 위해 리플렉션 기법을 사용하는데,
데이터 자동화 처리에서 제일 중요한 것은 표준규격입니다.
예를들어 윗 클래스 DTO에서 property가 name, age라면 name, age의 키값으로 들어온 데이터는
리플렉션 기법으로 setter를 실행시켜 데이터를 넣을 수 있습니다.
중요한 것은, 우리가 setter를 요청하는 것이 아닌 프레임워크 내부에서 setter가 실행된다는 점입니다.(눈에 보이지않음)

그래서 layer간(특히 서버 -> View로 이동 등)에 데이터를 넘길때에는 DTO를 쓰면 편하다는 것이 이런이유 때문입니다.
View에 있는 form에서 name 필드 값을 프로퍼티에 맞춰 넘겼을 때, 받아야 하는 곳에서는 일일히 처리하는 것이 아니라
name속성의 이름이랑 매칭되는 프로퍼티에 자동적으로 DTO가 인스턴스화 되어 PersonDTO를 자료형으로 값을 받을 수 있습니다.
그래서 key-value 로 존재하는 데이터는 자동화 처리된 DTO로 변환되어 쉽게 데이터가 셋팅된 오브젝트를 받을 수 있습니다.
[ 출처 ]


VO (Value Object)

VO(Value Object)는 말 그대로 값 오브젝트로써 값을 위해 쓰입니다.
VO는 변하지 않는 데이터 객체를 의미합니다.
오직 read만 가능하며 getter만 가능해야 합니다.

VO는 DTO와 차별화되는 점이 몇 가지 있습니다.
하나는 객체의 불변성(객체의 정보가 변경되지 않음)을 보장합니다. 즉, 값을 설정한 뒤에는 수정할 수 없습니다.(Setter (X))
다른 하나는 equals()hashCode()재정의(Override) 해서 각 객체의 동일성을 판별할 수 있습니다.

VO는 그럼 어떤 경우에 사용해야 할까?
  • 데이터가 불변이어야 하고, 단순히 저장된 값을 불러와야 하는 경우

(ex. 서울의 지역번호는 누구나 다 알듯 02입니다. 그리고 핸드폰 번호처럼 변하는 게 아닌 고정된 값입니다.
그렇기 때문에 위와 같이 고정된 값은 VO로 저장 후 Getter 호출 합니다.)


DTOVO의 차이점

DTO는 데이터의 전송만을 위한 객체이고, VO는 특정한 비즈니스 로직을 가질 수 있습니다.

DTO는 데이터 전달만을 목적으로 하고, VO는 객체 자체를 어떠한 값(Value)으로서 사용합니다.
(외부 시스템과 데이터 통신을 할 경우 DTO로, DB에서 가져오는 Data는 VO로 정의 후 사용)

DTO는 목적 자체가 데이터의 전달이므로, 읽고 쓰는 것이 모두 가능해 가변성을 갖고,
VO는 불변성 및 read-only의 속성을 갖습니다.

VO는  equals()와 hashCode()를 재정의(Override) 해서 각 객체의 동일성을 판별할 수 있습니다.
간단하게
DTO a = new DTO(1);
DTO b = new DTO(1);
라고 했을때 a != b 이지만,
VO a = new VO(1);
VO b = new VO(1);
라고 했을때 a==b 입니다.


반응형

블로그의 정보

슬기로운 개발생활

coco3o

활동하기