DAO와 DTO | Repository랑 Domain..?
국비학원에서 JSP / Servlet과 Mybatis를 배우면서, 또 개인적으로 Spring을 공부하면서 만난 다양한 용어들 중 혼동되는 용어들이 있어서 이러한 개념들을 정리하는 차원에서 MVC 패턴, DAO, DTO 등을 정리해보는 시간을 가져보려한다.
공부하는 학생이 작성하는 글이기 때문에 정보에 오류가 있을 수 있음을 알립니다!
MVC 패턴
김영한님의 스프링 수업을 들으며 본격적으로 알게되었던 MVC 패턴은 소프트웨어 개발을 각각 Model-View-Controller로 나누어 역할을 분담하는 디자인 패턴을 말한다. 웹개발을 할 때 특히 흔히 마주하게 되는 디자인 패턴으로 클라이언트단에서 보여지는 화면과 서버 내에서의 비지니스 로직, 그리고 DB에 접근하는 요소를 구분하는데 중점을 둔다. MVC 패턴의 세 부분은 다음과 같이 설명이 가능하다.
- Model - 데이터 혹은 비지니스 로직을 담는 영역이다. Controller로부터 클라이언트의 요청을 인계 받은 서버가 클라이언트의 요청을 처리하기 위해 데이터를 준비하거나 가공하는 작업이 이곳에서 수행된다.
- View - 클라이언트에게 보여지는 html 파일을 포함한 화면 전반을 담당하는 영역이다. html을 꾸미기 위한 css나 DOM 요소를 조작하기 위한 웹 상에서의 js도 이곳에 위치한다.
- Controller - View와 Model 사이에서 각각의 요청과 응답을 중개하는 영역이다. 필요한 곳으로 명령을 라우팅한다.
서버를 기차로 비유를 하자면 기차의 앞쪽 칸은 View 영역, 뒷쪽 칸은 Model 영역, 그리고 중간 영역은 Controller 영역이랄까? View는 클라이언트(사용자, user)의 요청을 접수해 Controller에 보내고 Controller는 이를 담당 Model에게 보내고 Model은 이를 적당히 조작하고 가공해 클라이언트에게 전송하는 형식이다.
여기까지는 크게 어렵지 않았는데, 국비지원 수업을 들으며 생소한 단어들을 듣기 시작하면서 개념들이 꼬이기 시작했다. Spring 수업을 들을 때 김영한님이 말씀해주신 Model 내 개념들의 명칭과 국비지원 강사님이 설명해주신 명칭들이 서로 달랐기 때문. 구체적인 용어 차이는 다음과 같다. (사실 중요하지는 않다. 용어들이 많아서 오히려 복잡해질지도..)
Model 안의 세부적인 개념들
- 김영한님이 사용한 용어 - Service, Domain, Repository
- 국비지원 강사님이 사용한 용어 - Service, DTO, DAO
도대체 DTO랑 DAO가 뭐란 말인가. 너무 궁금한 나머지 조사를 하기 시작했다. 아래의 정리는 이러한 조사의 결과물.
DAO (Data Access Object)
우선 조사의 결론부터 말하자면 모든 혼란은 스프링과 JSP/Servlet의 사용이 같은 java를 사용한다고 해서 1:1로 대응되지 않았기 때문에 벌어진 일이었다. 나는 JSP와 Servlet을 경험하기 전에 미리 스프링을 공부했었고, MVC 패턴을 스프링 식으로 처음 배웠기 때문에 같은 역할을 하는 요소가 서로 다른 개념과 이름으로 존재할 수 있다는 것을 인지하지 못했던 것이었다.
DAO는 스프링에서의 Repository와 대응될 수 있는 개념이다. 서버의 가장 끝단에서 실제로 DB에 접근하는 객체. 실제 물리적인 데이터를 조작하는 기능을 전담하는 오브젝트 말이다. JDBC에서의 DB Connection Pool이 발전해 DAO가 되고, 그것의 역할을 스프링에서는 Repository가 전담하는 것으로 보인다. 결국은.. Repository와 DAO는 같은 역할을 맡는 객체들이라는 것. (보다 자세한 정보는 이 글을 살펴보도록 하자. -> DB Connection Pool에 대한 이야기)
그러나 앞서 설명했듯 DAO와 Repository를 같은 것으로 보는 것에는 무리가 있는 듯 하다. 이와 관련된 글이 하나 있는데 DAO와 Repository의 차이에 대해 설명해주고 있다. 한번 읽어보는 것도 유익할 것 같아 첨부한다.
DAO와 REPOSITORY 모두 퍼시스턴스 로직에 대한 객체-지향적인 인터페이스를 제공하고 도메인 로직과 퍼시스턴스 로직을 분리하여 관심의 분리(separation of concerns) 원리를 만족시키는데 목적이 있다. 그러나 비록 의도와 인터페이스의 메소드 시그니처에 유사성이 존재한다고 해서 DAO와 REPOSITORY를 동일한 패턴으로 취급하는 것은 성급한 일반화의 오류를 범하는 것이다.
DAO는 퍼시스턴스 로직인 Entity Bean을 대체하기 위해 만들어진 개념이다. DAO가 비록 객체-지향적인 인터페이스를 제공하려는 의도를 가지고 있다고 하더라도 실제 개발 시에는 하부의 퍼시스턴스 메커니즘이 데이터베이스라는 사실을 숨기려고 하지 않는다. DAO의 인터페이스는 데이터베이스의 CRUD 쿼리와 1:1 매칭되는 세밀한 단위의 오퍼레이션을 제공한다. 반면 REPOSITORY는 메모리에 로드된 객체 컬렉션에 대한 집합 처리를 위한 인터페이스를 제공한다. DAO가 제공하는 오퍼레이션이 REPOSITORY 가 제공하는 오퍼레이션보다 더 세밀하며, 결과적으로 REPOSITORY에서 제공하는 하나의 오퍼레이션이 DAO의 여러 오퍼레이션에 매핑되는 것이 일반적이다. 따라서 하나의 REPOSITORY 내부에서 다수의 DAO를 호출하는 방식으로 REPOSITORY를 구현할 수 있다.
DAO와 REPOSITORY 논쟁(http://egloos.zum.com/aeternum/v/1160846)
DTO (Data Transfer Object)
사실 DAO와 DTO는 단어의 뜻(Access, Tranfer)에서 유추할 수 있듯 각각 데이터베이스에 '접근'하는 객체, 데이터를 '전송'하는 객체를 말한다. DTO는 DAO로부터 조회한 데이터를 Service나 Controller 등으로 전달하기 위한 객체로 실제 DB의 값이 서버 내의 로직들에 의해 조작되지 않게 하기 위해 사용된다. 역할이 단순히 '교환 및 전달'이기 때문에 특별한 로직을 가지지는 않고 getter / setter 메소드만을 갖는다. DAO로부터 전달받은 데이터를 프론트엔드와 서버단에서 안전하게 사용하게 하기 위해 사용하는.. 일종의 상자랄까..?
앞서 DAO와 Repository가 유사한 역할을 수행하는 객체였던 것과는 달리 Domain과 DTO는 서로 역할 자체가 다르다. DTO는 데이터를 전달하는 객체이기 때문에 별다른 로직을 갖지 않는 반면에 Domain은 핵심 비지니스 로직을 담는 영역이기 때문에 그에 맞는 비지니스 로직을 가질 수 있다. 즉 서로의 관심사가 다른 것인데, DTO와는 달리 Domain은 단순히 다른 계층에 데이터를 전달하고 교환하는 역할만을 갖지 않는 것.
.. 그러나 아직은 잘 모르겠다. 이 부분은 조금 더 공부가 필요할 것 같다.