MutiLayeredProject는 View
- ViewModel
- UseCase
- Repository
- DataSource
- Retrofit
과 같은 모듈들로 분리되어 있다. 아래는 Now In Android
의 프로젝트 구조이다.
MultiLayeredProject를 처음 보는 사람이면, '왜 굳이 Model
들을 분리해 놓지?' 라는 의문이 들 수 있으며 나 또한 그랬다. 아래는 OfflineFirstNewsRepository
의 내부 코드이며, Room
의 Entity
모델인 PopulatedNewsResource
을 Repository
전용 모델인 NewsResource
로 파싱해주고 있는 부분이다.
사실상, 프로젝트가 간단하고, 변경이 많이 예상되지 않는다면 위와 같은 구조는 필요 없을 수도 있다. 하지만 그게 아니라면 Repository
전용 모델을 추가로 정의하고 파싱하는 코드는 앱을 구성하는 괜찮은 방법 중 한가지일 수도 있다.
MultiLayeredProject가 존재하며, 상위, 하위 모듈 모두 API의 ResponseModel에 의존한다고 가정해보자. 위와 같은 프로젝트의 장단점은 아래와 같다.
[장점]
ResponseModel
을 공유함으로써 불필요한 클래스 정의를 안해도 된다. 이로써 소스코드 양이 줄어들며, 패키지 정리에 따른 비용이 덜 든다.[단점]
ResponseModel
에 변경이 생겼을 때, Repository
, ViewModel
, View
의 연쇄적인 수정을 해야할 수도 있다. 만약, 빠르게 성장중인 앱이라면 유지보수 비용은 더 높아질 수 있다.[장점]
ResponseModel
의 변경은 Repository
까지밖에 전파되지 않으므로, Repository
모듈쪽만 적절히 작업해주면 상위 Layer들의 영향을 줄일 수 있다.Repository
를 여러 ViewModel
or UseCase
들이 공유가 잦은)일수록, 다른 Layer들의 변경을 줄일 수 있다.[단점]
class
들이 증가한다. (윗 쪽의 NewsResource
와 PopulatedNewsResource
처럼)아래의 경우, DataModel을 추가로 정의하면 좋다고 생각한다.
- 앱의 잦은 변경 및 빠른 배포를 통해 성장중인 APP의 경우
- 하나의
Repository
를 여러ViewModel
orUseCase
들이 공유하는 큰 규모의 APP의 경우
만약 위, 2가지 모두 해당하는 APP일 경우, DataModel
뿐만 아니라, UiModel
을 추가로 정의하는 것도 하나의 방법이 될 수 있다.
하지만, 위의 구조로 작업할 떈, 반드시 어떤 Layer에 어떤 모델을 정의할지, 사전 설계를 숙고하여 진행할 필요가 있다.
예를 들어, 신규 구축 프로젝트의 경우, 기획서를 철저히 분석하고, 도메인을 정의하며, 각 데이터들을 그룹화하는 작업을 통해 모델링 작업이 선행돼야 한다. 이에, 첫 번째로 필요한 부분이 바로 Repository
라고 생각한다.
앱에서 사용되는 도메인 관련 데이터들을 그룹화하고 이를 각각의 Repository
로 정의하는 것이다. 또한 이런 취지에 알맞게, NowInAndroid
에선 아래의 말을 하고 있다.
Each repository has its own models. For example, the TopicsRepository has a Topic model and the NewsRepository has a NewsResource model.