이전에 DAO? DTO? VO? Entity? 포스트에서 관련된 내용을 정리한 적이 있다. 이해하는 것이 목적이였기 때문에 깊이 생각해보지 않고 넘어갔었다. 그 중, 내가 정리한 내용 중에서 DAO(Data Access Object)는 JPA에서의 Repository의 기능과 동일한 역할을 수행한다고 했었다. 과연 정말로 DAO와 JPA에서의 Repository가 동일하다고 할 수 있을까? 😆
우리는 MySQL, Oracle, MongoDB 등 다양한 영구 저장소의 구현체를 사용해왔다. 그리고 어플리케이션에서 이러한 저장소에 접근하기 위해 벤더별로 저장소에서 제공하는 API를 통해 접근해왔다. 이 과정에서 어떤 문제가 있었을까?
구현체와 로직의 강한 결합 문제
만약 MySQL과 같은 특정 벤더의 영구 저장소를 사용하고 있을때, Oracle로 변경해야 한다면, MySQL의 API를 사용한 모든 구현을 변경해주어야 하는 불편함이 생긴다.
계층간 간섭 문제
레이어가 깨지는 문제는 결국 강한 결합 문제로 연결된다. MySQL의 API를 서비스 로직에서 사용했을 경우, 서비스 로직과 DB와 관련된 API가 강한 결합을 가지게 되어 영속성과 관련된 로직이 서비스 로직에 영향을 미치는 문제가 발생한다. 즉, 서비스 계층과 인프라 계층(영속성 계층)간의 결합이 강해지는 문제가 생긴다는 것이다.
개발자의 학습 영역이 증가
각 저장소는 벤더별로 특징이 모두 다르다. 따라서 그 특징마다 다른 구현을 가지기 때문에 개발자의 학습 영역은 증가할 수 밖에 없다.
위의 문제들을 해결하기 위해 나온것이 바로 DAO 패턴이다. DAO 패턴은 벤더들의 API와 로직 사이에 있는 어댑터와 같은 역할을 수행한다.
DAO가 어댑터의 역할을 수행하기 때문에 밴더의 구현체를 그대로 사용하지 않고 DAO 객체를 이용하여 데이터 소스가 변경되더라도 그 로직에는 변화가 없도록 하는 강한 결합 문제를 해결했고, 각 벤더별 구현의 차이점을 극복했다는 점에서 개발자의 학습 영역에 대한 부담감이 덜 수 있었다. (레이어가 깨지는 문제점은 각 계층간 전달되는 데이터 객체인 DTO를 만들어 해결)
바로 본론으로 넘어가보자.
지금 내가 작업하고 있는 프로젝트나 다른 블로그에서 작성된 글만 보아도, Repository는 domain 패키지로 분류하는 것을 볼 수 있다. 하지만 위의 내용대로라면, Repository는 인프라 계층에 속해 있어야 한다. 음..? 그럼 Repository는 도메인 계층인가 아니면 인프라 계층인가?
정의부터 내리자면 Repository는 객체의 상태를 관리하는 저장소다. 즉, Repository는 영구 저장소를 의미하는 것이 아니고 객체의 상태를 관리하는 저장소라는 것이다. 따라서 도메인 정보를 가지고 있어야 하는 Repository는 인프라 계층이 아닌 도메인 계층이라는 점이 맞다는 것이다! 🤔
💡 Repository는 서비스 계층이라고 하는게 맞지 않나?
Repository는 보통 서비스 로직에서 사용하기 때문에 도메인 계층이 아닌 서비스 계층이라고 생각할 수 있지만, 더 깊에 들어가기 위해서는 DDD에 대한 공부가 필요하므로 여기서는 Repository가 도메인 계층이다는 것만 이해하고 넘어가자. 😜
사용 경험상의 혼동이 아닌 더 핵심적인 혼동 원인을 생각해보자.
이유는 간단하다. Repository는 인터페이스이고, 이 인터페이스의 구현체는 영구 저장소 API를 이용해 구현하기 때문에 영구 저장소인것 마냥 사용했기 때문이다. 즉, Repository 구현체는 인프라 계층에 속해있지만 Repository 인터페이스 자체는 도메인 계층에 속한다는 것이다.
추가적으로 클라이언트는 Repository가 어떻게 구현이 되어있는지 모르고 기능만을 사용한다는 점에서 DAO 의 어댑터 패턴 특징과 동일하다는 것도 알 수 있다.
내가 이해한 바를 토대로 정리하자면 DAO와 Repositroy는 구현체가 보이느냐 안보이느냐의 차이인 것 같다.
제대로 이해했는지는 모르겠으나, 개인적으로는 이 두 개념의 차이는 없다고 생각한다. 더 정확하게 이해하기 위해서는 DDD에 대한 공부가 필요해보인다. 나중에 DDD에 대한 공부를 하면서 다시 개념을 잡아보도록 해보자.
(아래에 첨부해놓은 링크들에서는 DAL(Data Access Layer)를 구현하는 방식에 차이가 있다고도 했는데, 결국 위에서 말하는 내용과 동일한 것 같으니 한번 읽는 용도로만 참고하면 좋을 것 같다.)