[Web Application] DTO vs VO vs Entity

YJ KIM·2022년 9월 28일
1

BackEnd

목록 보기
2/2
post-custom-banner

Spring, Spring boot를 써오면서 DTO, VO, Entity에 대해 많이 들었고 실제로 많이 써봤지만 정확히 어떤 개념인지에 대해 설명할 수 없어서 이 포스팅을 작성하게 되었다.

목차

  1. DTO
  2. VO
  3. Entity
  4. DTO vs VO
  5. DTO vs Entity
  6. 정리

📂 참고 사이트
[10분 테코톡] 🎼라흐의 DTO vs VO
[10분 테코톡] 📍인비의 DTO vs VO

위 두개의 동영상을 참고했다.

1. DTO란?

DTO, Data Transfer Object로 말 그대로 '데이터 이동을 위한 객체' 라고 생각하면 된다.
여기서의 데이터 이동이란 웹 어플리케이션 계층 간 데이터 이동을 말한다.

1-1. 웹 어플리케이션 계층


(위의 그림은 web application layer을 매우 간소화 한 것이라고 생각한다. 원래는 control 계층 등 여러 계층이 더 있어야 하지 않나? 싶다. 아마 여기서는 presentation layer에 controller 가 포함된다고 생각한 것 같다. )

Spring, Spring boot를 사용한 사람이라면 컨트롤러, 서비스, 레포지토리에 대한 개념을 알고 있을 것이다.

🌍 내가 알고 있는 Web application의 흐름도

  1. client(사용자)가 Request를 Server에 보낸다.
  2. Controller 이전의 front-Controller인 DispatcherServlet이 Handler Mapping을 통하여 해당 Request를 처리할 Controller를 찾는다.
  3. Controller를 찾았으면 HandlerAdapter를 통하여 해당 Controller를 동작시킨다.
  4. 해당 Controller에서 Service Bean을 호출하여 비즈니스 로직을 수행한다.
  5. DB와 Repository를 연결하여 persistence Context에서 CRUD를 수행한다.

매우 많이 축약한 거긴 하지만 대략 이런 구조로 돌아간다고 생각한다.

1, 2, 3 : Control Layer
4: Business Layer
5: Persistence Layer

1-2. 그래서 계층이랑 무슨 상관인데?

맨 처음에, DTO란 데이터 이동을 위한 객체라고 정의했다.
만약 DB의 실제 테이블과 연동되는 Entity (후에 설명할 것이지만 대충 DB를 가져오는 객체라고 생각하면 된다.) 를 비즈니스 로직에 따라 이리저리 값을 바꿔주면 서비스에 큰 혼란이 온다. 그래서 계층을 기준으로 분리해주고 있다.

📍 DTO는 Entity를 그대로 서비스에 사용하면 혼란이 오기 때문에 단순히 값을 전달해주는 역할로만 사용한다.

2. VO란?

VO, Value Object로 말 그대로 '특정 값을 나타내는 객체'라고 생각하면 된다.
특정 값?... 처음엔 잘 와닿지 않았는데

주소가 다른 두 개의 객체가 존재할 때,
이 두 개의 속성 값(객체의 내부 변수 값들)이 다 동일하면
이는 같은 객체로 취급하는 게 VO의 중심 개념이다.
즉, 객체가 아닌 값에 집중한다는 것이다.

위에서 언급한 내용을 위해 Object의 equals, hashcode와 같은 메소드를 오버라이딩 하는 게 보편적인 것 같다!
(나는 웹 서버 코드 작성 시에, VO를 사용해본 경험이 적어서 아직까지는 구현해본 적이 없다.)

3. Entity란?

Entity란, 실제 DB의 테이블과 1:1로 매핑되는 클래스로, EntityManager가 관리한다. 좀 더 자세하게는, EntityManager 내부에 persistence context를 두어 이 Context에서 Entity를 관리한다고 보면 된다.

4. DTO vs VO

DTO는 데이터를 '전달' 하는 순수한 데이터 객체이기 때문에
Getter/Setter 이외의 다른 로직이 필요 없다.
🚨 하지만 Setter를 남발하면 데이터가 예상치 못하게 수정될 수 있기 때문에 Setter보다는 생성자로 값을 넣어주는 경우가 많다. 나 또한 DTO에는 Setter를 생성하지 않는다!

하지만, VO는 로직을 포함할 수 있으며 불변성의 보장을 위하여 생성자를 사용하여야 한다.
🚨 VO는 순수한 값을 나타내기 때문에 '불변성' 보장이 필수이다.

5. DTO vs Entity

DTO는 데이터 전달을 위한 데이터 객체이고,
Entity 실제 DB와 1:1로 매핑되는 클래스이다.

DB에 CRUD를 수행한 값을 Entity로 받아오는데, 이를 여러 layer에서 전달하고 전달받을 때 Entity의 형태로 받는 것보다 Entity -> DTO로 수정해서 전달하는 구조로 현재 대부분의 웹 어플리케이션이 수행되고 있다.

이유는 1-2에서 설명했다!

6. 📍정리

  • DTO: 데이터 전달을 위한 객체로 Getter/Setter만 구현하고 별도의 로직을 포함하지 않아야 한다. Only 데이터 전달만을 위한 객체이다.
  • VO: 값을 표현하기 위한 객체로, 로직을 포함할 수 있으며 VO는 순수한 값을 나타내기 때문에 불변성 보장이 필수이다. -> Setter 구현x
  • Entity: 실제 DB와 1:1로 매핑되는 클래스로 DTO, VO와 다르게 EntitiyManager가 관리하며 peresist Context에 존재한다. (Life Cycle이 다름). DTO와 다르게 DB가 변경될 수 있기 때문에 데이터 사용 시, Entity->DTO로 변경하여 사용하는 것이 보편적이다.

사실상 JPA를 사용하는 사람이라면 Entity에 대해서는 당연히 알 것이고,
DTO와 VO의 개념에 대해 헷갈렸는데(사실 몰랐음 ㅎ) 이 기회에 확실하게 알게 된 것 같다.
근데 생각보다 DTO 사용할 때 Setter 구현하는 사람이 많은 듯 ...
본인 코딩 스타일인지 싶다.. 혼자 하면 크게 상관은 없을 것 같다.

참고 자료

web apllication layer

profile
모르면 쓰지 말고 쓸 거면 알고 쓰자
post-custom-banner

0개의 댓글