Spring, Spring boot를 써오면서 DTO, VO, Entity에 대해 많이 들었고 실제로 많이 써봤지만 정확히 어떤 개념인지에 대해 설명할 수 없어서 이 포스팅을 작성하게 되었다.
목차
- DTO
- VO
- Entity
- DTO vs VO
- DTO vs Entity
- 정리
📂 참고 사이트
[10분 테코톡] 🎼라흐의 DTO vs VO
[10분 테코톡] 📍인비의 DTO vs VO
위 두개의 동영상을 참고했다.
DTO, Data Transfer Object로 말 그대로 '데이터 이동을 위한 객체' 라고 생각하면 된다.
여기서의 데이터 이동이란 웹 어플리케이션 계층 간 데이터 이동을 말한다.
(위의 그림은 web application layer을 매우 간소화 한 것이라고 생각한다. 원래는 control 계층 등 여러 계층이 더 있어야 하지 않나? 싶다. 아마 여기서는 presentation layer에 controller 가 포함된다고 생각한 것 같다. )
Spring, Spring boot를 사용한 사람이라면 컨트롤러, 서비스, 레포지토리에 대한 개념을 알고 있을 것이다.
🌍 내가 알고 있는 Web application의 흐름도
- client(사용자)가 Request를 Server에 보낸다.
- Controller 이전의 front-Controller인 DispatcherServlet이 Handler Mapping을 통하여 해당 Request를 처리할 Controller를 찾는다.
- Controller를 찾았으면 HandlerAdapter를 통하여 해당 Controller를 동작시킨다.
- 해당 Controller에서 Service Bean을 호출하여 비즈니스 로직을 수행한다.
- DB와 Repository를 연결하여 persistence Context에서 CRUD를 수행한다.
매우 많이 축약한 거긴 하지만 대략 이런 구조로 돌아간다고 생각한다.
1, 2, 3 : Control Layer
4: Business Layer
5: Persistence Layer
맨 처음에, DTO란 데이터 이동을 위한 객체라고 정의했다.
만약 DB의 실제 테이블과 연동되는 Entity (후에 설명할 것이지만 대충 DB를 가져오는 객체라고 생각하면 된다.) 를 비즈니스 로직에 따라 이리저리 값을 바꿔주면 서비스에 큰 혼란이 온다. 그래서 계층을 기준으로 분리해주고 있다.
📍 DTO는 Entity를 그대로 서비스에 사용하면 혼란이 오기 때문에 단순히 값을 전달해주는 역할로만 사용한다.
VO, Value Object로 말 그대로 '특정 값을 나타내는 객체'라고 생각하면 된다.
특정 값?... 처음엔 잘 와닿지 않았는데
주소가 다른 두 개의 객체가 존재할 때,
이 두 개의 속성 값(객체의 내부 변수 값들)이 다 동일하면
이는 같은 객체로 취급하는 게 VO의 중심 개념이다.
즉, 객체가 아닌 값에 집중한다는 것이다.
위에서 언급한 내용을 위해 Object의 equals, hashcode와 같은 메소드를 오버라이딩 하는 게 보편적인 것 같다!
(나는 웹 서버 코드 작성 시에, VO를 사용해본 경험이 적어서 아직까지는 구현해본 적이 없다.)
Entity란, 실제 DB의 테이블과 1:1로 매핑되는 클래스로, EntityManager가 관리한다. 좀 더 자세하게는, EntityManager 내부에 persistence context를 두어 이 Context에서 Entity를 관리한다고 보면 된다.
DTO는 데이터를 '전달' 하는 순수한 데이터 객체이기 때문에
Getter/Setter 이외의 다른 로직이 필요 없다.
🚨 하지만 Setter를 남발하면 데이터가 예상치 못하게 수정될 수 있기 때문에 Setter보다는 생성자로 값을 넣어주는 경우가 많다. 나 또한 DTO에는 Setter를 생성하지 않는다!
하지만, VO는 로직을 포함할 수 있으며 불변성의 보장을 위하여 생성자를 사용하여야 한다.
🚨 VO는 순수한 값을 나타내기 때문에 '불변성' 보장이 필수이다.
DTO는 데이터 전달을 위한 데이터 객체이고,
Entity 실제 DB와 1:1로 매핑되는 클래스이다.
DB에 CRUD를 수행한 값을 Entity로 받아오는데, 이를 여러 layer에서 전달하고 전달받을 때 Entity의 형태로 받는 것보다 Entity -> DTO로 수정해서 전달하는 구조로 현재 대부분의 웹 어플리케이션이 수행되고 있다.
이유는 1-2에서 설명했다!
사실상 JPA를 사용하는 사람이라면 Entity에 대해서는 당연히 알 것이고,
DTO와 VO의 개념에 대해 헷갈렸는데(사실 몰랐음 ㅎ) 이 기회에 확실하게 알게 된 것 같다.
근데 생각보다 DTO 사용할 때 Setter 구현하는 사람이 많은 듯 ...
본인 코딩 스타일인지 싶다.. 혼자 하면 크게 상관은 없을 것 같다.