스프링을 사용하면서 처음 Layered Architecture를 적용하여 프로그램을 구현하게 되었고, 기존 콘솔 애플리케이션에서 사용하던 Model-View-Controller 이외에 서비스 계층, DAO 계층이 생겼습니다.

MVC패턴을 사용할 때는 Controller ↔ View 사이의 데이터를 주고 받을 때 DTO를 통해 데이터를 전달하는 것이 명확했습니다. 따라서 View에서 사용되는 데이터와 도메인에서 사용되는 데이터를 구분하기 위해 DTO를 사용했고, 뷰와 도메인을 구분해주는 컨트롤러가 DTO를 생성해주어야 한다는 것도 명확했습니다. 하지만 Service 계층이 추가되면서 어느 계층까지 DTO를 사용해야하는지, 그리고 DTO를 도메인으로 변환해주는 역할의 책임이 어느 계층에 있는지 모호해졌습니다.

DTO를 어느 레이어에서 변환해줄 것인지를 명확히하기 위해 먼저 DTO와 각 계층의 역할을 한 번 더 공부해보았습니다.

DTO란 무엇일까?

Data Transfer Object DTO는 말 그대로 데이터 전송을 위한 객체입니다.

레벨1에서 DTO를 사용해본 크루라면

DTO에 너무 많은 로직이 들어가있습니다. DTO에 대해 조금 더 학습해보면 어떨까요?

와 같은 피드백을 받아본 경험이 있을 것 같습니다. DTO에 대해 조금 공부해보면 DTO에는 비즈니스 로직이 포함되면 안되고 단순히 값을 저장하기 위한 로직이나 getter만을 가져야 한다는 것을 알 수 있습니다.

Baeldung에서는 DTO의 역할을 다음과 같이 정의합니다.

They are flat data structures that contain no business logic. They only contain storage, accessors and eventually methods related to serialization or parsing.

DTO는 비즈니스 로직을 갖지 않고, 저장이나 접근, 또는 직렬화등을 위해서만 사용되어야 하며, 일반적으로 도메인은 프레젠테이션 레이어에 위치한 Mapper에 의해 DTO로 변환되어야 합니다.

(*직렬화: 서버가 DTO와 같은 객체를 JSON 형식으로 변환하는 것) (*역직렬화: 서버가 JSON 형식의 데이터를 DTO와 같은 자바 객체로 변환하는 것)

DTO의 사용 이유

그렇다면 왜 DTO를 사용하는 것일까요?

조금 다른 길로 새어 DTO를 사용하는 이유를 마틴 파울러와 밸덩에서는 다음과 같이 이야기합니다.

An object that carries data between processes in order to reduce the number of method calls. Martin Folwer

DTOs or Data Transfer Objects are objects that carry data between processes in order to reduce the number of methods calls.Baeldung

= 메서드 호출 횟수를 줄이기 위해 프로세스 간에 데이터를 전달하는 개체

저는 지금까지 DTO를 데이터를 전송하는 객체로만 알고 있었고, DTO에 데이터를 포장하면서 데이터를 포장하기 위해 ‘데이터 캡슐화’를 위해 DTO로 포장해야 한다고 생각했는데, 사실 데이터의 캡슐화는 DTO를 사용함으로써 얻게 되는 베네핏이었던 것이지요!

마틴 파울러가 처음 DTO 개념을 소개하게된 이유는 *in order to reduce the number of method calls.* 즉, 메서드의 호출을 줄이기 위함이었습니다. 메서드 호출에는 비용이 들고, 비용을 최소화하기 위해서는 메서드 호출 횟수를 줄여야합니다. 이를 위한 방법으로는 여러개의 파라미터를 사용하는 방법도 있지만, 파라미터를 많이 사용하는 것은 클린 코드를 위해 지양해야 하는 방식입니다.