티스토리 뷰

Repository Pattern

(by Edward Hieatt and Rob Mee)Repository (레파지토리) 패턴은 아키텍처라기보다는 디자인 패턴중에 하나인데 데이터가 있는 어떤 저장소이든 간에 데이터를 사용하는 로직에서 분리시키는 것을 목적으로 한다. 아래는 Martin Fowler의 Patterns of Enterprise Application Architecture (P of EAA)에서의 정의다.

도메인과 데이터 사이를 중재하는 매핑 레이어로 도메인 객체에 접근하기 위한 콜렉션과 같은 인터페이스를 사용한다.
<!--여기서 말하는 도메인은 프로그램이 구현하고자 하는 문제 즉, 어떤 기능으로 볼 수 있다. 일반적으로는 소프트웨어에서 도메인은 소프트웨어를 적용하는 그 분야의 환경을 의미하고 (예를 들어 의료, 이커머스, 교통 등) 도메인이 특별히 가지는 용어와 컨셉으로 요구사항이 표현될 수 있다.-->

도메인은 필요한 데이터를 레파지토리에 요청하고, 레파지토리는 도메인이 요청한 정보를 데이터를 가공해서 보내준다. 이 패턴을 사용하는 장점은 도메인이 실제로 어떤 데이터를 사용하는지는 알지 못하기 때문에 환경에 맞는 데이터를 사용하기 편리하다는 것이다.

위의 그림을 보면 테스트 환경에서는 In-Memory 데이터를 사용하고 프로덕션 환경에서는 원격 서버에 있는 DB의 데이터를 사용하지만 도메인은 두 경우 모두 변함이 없다. 바뀌는 부분은 레파지토리의 실제 구현인데 추상화된 Repository 클래스로 구현된 클래스들이 싸여져 있어 도메인은 언제나 같은 인터페이스로 요청을 할 수 있다.

복잡한 도메인 모델을 가지는 시스템은 데이터 매핑하는 레이어를 두어 레이어를 장점으로 이용할 수 있다. 그렇게 하면 도메인 객체를 상세한 데이터베이스 접근 코드에서 분리시킬 수 있게 된다. 데이터베이스 쿼리를 구현하는 코드가 만들어지는 매핑레이어로 또다른 추상화 레이어를 만드는 것이다. 이 패턴은 수많은 도메인 클래스들 또는 복잡한 쿼리를 가질 때 더 중요하다. 특히 이런 경우 이 레이어를 더하는 것은 쿼리 로직의 중복을 최소화하는데 도움이 된다.

Repository는 도메인과 데이터 매핑 레이어들 사이를 중재해서 in-memory 도메인 객체 콜렉션 같은 역할을 한다. 클라이언트 객체는 쿼리 명세를 선언적으로 만들고 만족하는 Repository에 보낸다. 객체는 Repository에 추가되거나 제거될 수 있다. 그리고 Repository에서 캡슐화되는 매핑 코드는 안보이는 곳에서 적절한 작동을 한다. 개념적으로 Repository는 데이터 저장소에 있는 객체 집합을 캡슐화하고 더욱 더 객체 기반적인 뷰를 제공한다. 그리고 Repository는 깔끔한 분리를 추구하고 도메인과 데이터 매핑 레이어간 단방향 의존성을 지원한다.

참고문헌에서

Repository 패턴은 MVP 아키텍처에서도 사용된다. Android MVP 아키텍처를 예를 들면 Activity, Fragment 등의 View가 Presenter에게 어떤 기능을 요청하면 Presenter는 Model에서 데이터를 받아와 가공한 뒤 View에게 콜백한다. 이 과정에서 Presenter는 Model에게 어떻게 요청을 보내고 데이터를 받아올 수 있을까? 직접 DB 쿼리를 할 수도 있겠지만 그러면 Presenter와 Model이 서로 의존하게 된다.

이때 Presenter와 Model사이 Repository가 중재 역할을 할 수 있다. Presenter는 Repository의 인터페이스를 통해 필요한 데이터를 요청하고 Repository는 Presenter가 직접적으로 어떤 데이터를 사용하는지는 알 수없게 하며 데이터를 어딘가에서 가져와 Presenter에게 넘겨준다. 이 때 Presenter는 Repository 패턴의 Domain 역할을 한다고 볼 수 있다. 실제로 Presenter의 역할은 비즈니스 로직 즉, 기능 구현이기 때문에 일맥상통한다.

Repository는 MVP 아키텍처의 옵션이다. 만약 Model이 복잡하지 않고 환경이 변하지 않는다면 굳이 사용하지 않아도 된다. 여기서 Repository는 데이터는 아니지만 필요한 데이터를 쿼리하는 로직이기 때문에 비즈니스 로직 혹은 유즈케이스를 구현하는 Presenter보다는 Model에 속하는 것이 맞다고 생각하는데 안드로이드 패키지를 구조화할 때 domain 패키지 안에 repository를 넣는 경우도 있다. 어디에 속하든 중요한 것은 모델과 비즈니스 로직을 분리하는 것이다.

Repository 패턴을 사용하는 MVP 패턴은 다음과 같은 다이어그램이으로 결론지을 수 있을 것 같다.

참고 문헌

https://martinfowler.com/eaaCatalog/repository.html

댓글