DTO vs VO vs Entity
우리가 Spring Framework를 사용하면서 비슷한 개념이라고 생각했던 DTO, VO, Entity의 개념 및 차이점을 정리한다.
1. DTO (Data Transfer Object)
DTO(Data Transfer Object)는 데이터 전송(이동) 객체(Java Beans)라는 의미를 갖는다.
DTO는 계층(Layer)간 데이터를 주고 받을 때(주로 비동기) 사용하며, 주로 View와 Controller 사이에서 데이터를 주고 받을 때 활용하고 로직을 갖지 않는 순수한 데이터 객체이며, getter/setter 메소드만을 갖는다.
아래코드는 setter
를 가지는 경우로 가변 객체로 활용한 경우이다.
public class StudentDTO {
private int num;
private String name;
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
아래처럼 setter
가 아닌 생성자
를 이용해 초기화 하는 경우 불변 객체로 활용할 수 있다. 불변 객체로 만들면 데이터를 전달하는 과정에서 데이터가 변되지 않음을 보장할 수 있게된다.
public class StudentDTO {
private final int num;
private final String name;
public StudentDTO(int num, String name) {
this.num = num;
this.name = name;
}
public int getNum() {
return num;
}
public String getName() {
return name;
}
}
2. VO (Value Object)
VO(Value Object)는 말 그대로 값 오브젝트로써 값 자체를 표현하는 객체이다.
VOP는 변하지 않는 데이터 객체(객체의 불변성 보장)를 의미하고 오직 read만 가능하며 setter메소드는 갖지 않는다.
또, 값의 비교를 위해 equals()와 hashcode()를 재정의(Overide) 하여 VO 내부에 선언된 속성(Field)의 모든 값들이 VO 객체마다 값이 같아야, 똑같은 객체라고 판별한다.
* equals()와 hashCode() 메소드를 오버라이딩 하지 않으면 오류 발생
이러한 VO는 데이터가 불변이어야 하고, 단순히 저장된 값을 불러와 사용하는 경우
ex) 서울의 지역번호는 02이다. 가변하는 정보가 아닌 변하지 않는 고정된 값이기 때문에 위와 같이 고정된 값은 VO로 저장 후 Getter를 호출하여 사용한다.
✔️ DTO와 VO의 차이점
DTO는 데이터의 전송만을 위한 객체, VO는 특정한 비즈니스 로직을 가짐
DTO는 데이터 전달의 목적, VO는 객체 자체를 값(Value)으로 사용
(외부 시스템과 데이터 통신의 경우 DTO, DB에서 가져오는 Data는 VO로 정의 후 사용)
DTO는 읽고 쓰는 것이 모두 가능해 가변성을 갖고, VO는 불변성 및 read-only의 속성을 가짐
VO는 equals()와 hashCode()를 오버라이딩하여 각 객체의 동일선을 판별한다.
// 아래의 DTO의 경우 a != b
StudentDTO stuDTO1 = new StudentDTO(1, 'moon');
StudentDTO stuDTO2 = new StudentDTO(1, 'moon');
// 아래 VO의 경우 a == b
StudentVO a = new StudentVO(1, 'moon');
StudentVO b = new StudentVO(1, 'moon');
3. Entity
Entity 클래스는 실제 DataBase의 테이블과 1 : 1 로 매핑되는 클래스로, DB의 테이블 내에 존재하는 컬럼만을 속성(필드)로 가져야만 한다.
Entity 클래스는 상속을 받거나 구현체여서는 안되며, 테이블 내에 존재하지 않는 컬럼을 가져서도 안된다. 이러한 Entity 클래스는 가장 Core한 클래스라고 부른다.
따라서 Entity는 절대로 요청이나 응답값을 전달하는 클래스로 사용해서는 안되며 id
를 통해 각각의 Entity를 구분한다.
최대한 외부에서 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을 추가한 정도로 사용하며, Domain Model 객체는 Persistent만을 위해 사용해야 한다.
'Programming > Spring' 카테고리의 다른 글
[Spring] IoC 컨테이너에 등록된 Bean 조회하기 (0) | 2023.05.15 |
---|---|
[Spring] JPA 개념정리 (Hibernate, Spring Data JPA) (0) | 2023.05.08 |
[Spring] WebFlux란 무엇인가? - 개념(특징), MVC와 비교, 사용 이유 (0) | 2022.12.26 |
[Spring] MVC1, MVC2 개념 및 차이점 / Spring MVC 동작과정 (1) | 2022.07.17 |
[Spring] Mybatis - foreach 사용법 및 예제 / 동적 반복 sql 처리 (0) | 2022.06.26 |