DTO(Data Transfer Object)를 직역해보면, 데이터 전송(전달) 객체라는 뜻이다.
이미 만들어놓은 도메인 객체를 사용하면 될텐데, 왜 DTO라는 객체라는 개념을 만들어서 사용해야하는걸까?!
과연, Transfer 전달을 위해서만 필요한 객체일까?!
그럼 도메인 객체를 Controller - Service - Repository(스프링 3계층)에서 모두 사용했을 때의 장점과 단점부터 알아보자!
장점
- 하나의 객체만 사용하면, 관리할 것도 하나이기 때문에 편하다.
(개발자가)
단점
- Controller - Service - Repository(스프링 3계층) 간의 이동 시에 데이터가 변경될 수 있다.
낮은 데이터 신뢰성 - 사용자에게 보여줄 필요 없는(시스템에서 필요한) 데이터가 포함되어 이동되고, 사용자에게 보여주게 된다.
네트워크 비용 증가 및 낮은 보안 수준 - DB에는 저장되어 있지 않지만, 클라이언트에게 필요한 데이터가 있을 수 있다.
도메인 객체에 연산된 데이터를 저장할 수 없음 - 단일 책임 원칙이 깨진다
수정이 여러 곳에서 일어날 수 있다. (하나의 책임과 하나의 액터로 인한 변경이 아님)
위와 같은 단점으로 인해, 요청할 때와 요청 받을 때에 필요한 값만을 각각 저장할 수 있는 객체를 만들 필요성을 느끼게 된다.
+ MVC 패턴을 통해 Controller로 View와 Model 사이에 요청과 응답을 중개해줌으로써 계층간의 의존도를 낮췄는데, 하나의 객체를 모두 바라봄으로써 다시 의존도가 높아지게 되는 것이다!
그리고 각 Controller - Service - Repository(스프링 3계층) 간 이동을 하기 때문에, 이러한 객체를 우리는 DTO(Data Transfer Object)라 부르기로 했다.
DB와 직접적으로 연결된 원본 데이터가 아니기 때문에, 이로써 무결성을 보장하고 시스템의 신뢰성을 유지할 수 있게 되었다.
다시 장점 정리
- 도메인 객체를 캡슐화하여 보안을 강화
- DB 필드명과 동일하게 정할 필요가 없어, DB 필드명이 변경되어 도메인 객체(Entity) 필드명이 변경되었더라도 이를 노출시킬 필요가 없음
- 필요한 데이터만 선택적으로 보여주거나 받을 수 있음
그럼 Controller, Service 어디에서 객체 변환을 하면 좋을까?!
Service에서 front에 넘겨줘야할 값들을 고려해야한다는 점이 있지만, 그래도 Service에서 이러한 객체를 변환하는 작업을 해야한다고 생각한다.
왜냐하면, Controller는 요청과 응답을 넘겨주는 역할을 하는 계층이며 비즈니스로직까지는 알 필요가 없다고 생각하기 때문이다.
또한, DTO가 변경되어 로직이 변경되었다 하더라도, 요청을 받은 Service에서만 이러한 로직을 변경하면 된다고 생각하기 때문에, 변경 범위를 최소한으로 만들 수 있는 방법이라 생각한다.라고 어제까지의 나는 생각했다. (글 쓰고 다음 날 생각이 바껴, 지하철에 앉아 추가하는 글..ㅎㅎ) 핫 주관이 없는걸까개인적으로 진행하는 스터디에 DTO의 객체 변환은 어디서 해야하는지에 대한 주제를 가지고가서 의견을 나누며, 관점을 바꾸게 되었다.
우리가 정말 신경쓰면서 작성해야하는 부분은 비즈니스 로직을 처리해야하는 부분인 Service이다. Service에서 DTO와 Entity를 알게 된다면, JPA가 아닌 JDBC나 다른 곳에서 재사용하게 된다면, 이를 위해 Service의 코드를 변경해야한다.
(이러면 OCP원칙을 위반하게 되는 것 아닐까?)
이럴 때는 Domain이라는 객체를 하나 더 두어, 이 객치를 통해 Service에서는 오로지 비즈니스를 위한 로직만을 수행할 수 있도록 하여 객체지향적으로 구현이 가능할 수 있을 것 같다는 인사이트를 얻었다!
결론, 답은 없다. 타당한 이유만 있으면 된다~
참고
https://tecoble.techcourse.co.kr/post/2021-04-25-dto-layer-scope/
'프레임워크(Framework) > Spring' 카테고리의 다른 글
[Spring] DI의 생성자 주입 선호 이유를 테스트 코드에서 찾기(vs 필드 주입) (0) | 2024.07.30 |
---|---|
[Spring] Bean관리 누가할래? in TEST (@SpringBootTest @Test 알고 쓰기) (0) | 2024.07.30 |
[Spring] Data Binding의 3가지 방법 (0) | 2024.07.22 |
[Spring] IoC를 실현하기 위한 DI(의존 관계 주입) 방법 3가지 (0) | 2024.07.18 |
[Spring] @Component 와 @Autowired를 통해 IoC실현하기 (0) | 2024.07.17 |