본문 바로가기

Android/Architecture

[Android] Modular Architecture 예제

728x90

처음 학습하면서 작성한 글입니다. 필요시 추후 내용을 수정할 예정입니다.

틀린 부분이 있으면 언제든 지적해주면 감사하겠습니다 :)

해당 게시글에 사용한 예제 코드는 하단에 링크로 추가해두었습니다.


만들어둔 클린 아키텍처 예제 코드를 사용하여 Modular Architecture 구조의 예제를 만들어 보면서 학습하였다.

디테일하게 생각하여 모듈을 나눌 수 있지만, 처음부터 많은 모듈로 나눠서 사용하게 되면 복잡도만 올라가고 불필요한 코드만 늘어날 것이라고 생각하여 많은 부분을 모듈로 나누어서 사용하지 않았다.

 

해당 모듈러 아키텍처 예제를 만들면서, 기존 클린 아키텍처 예제에서 여러 가지를 추가해 두었다.

Coordination Pattern, AAC Navigation, DataStore 를 추가적으로 사용하여 넣어두었으며, 해당 기술들에 대한 자세한 설명은 다음 링크를 확인하면 될 것이다.

 

2022.02.15 - [Android/Design Pattern] - [Design Pattern] Coordinator Pattern

2022.02.17 - [Android/JetPack] - [Android] Jetpack DataStore 실전 압축 정리

2022.02.14 - [Android/AAC] - [AAC] AAC Navigation 사용 실전 압축 정리


우선, 기본 클린 아키텍처 구조인 Presentation, Data, Domain 의 3개 모듈에서

Presentation 부분을 화면에 따라서 여러 개의 모듈로 나누어 보았다.

 

실제로 사용하게 된다면 Data, Domain 또한 공통된 부분을 모듈로 뽑아내고 화면에 따라서 나누어질 수 있지만, 현재 예제에서는 실제 API 를 통해 데이터를 가져와서 뿌려주는 부분은 한 곳 밖에 없으므로 이런 식으로 예제를 만들어 보았다.

 

 

Presentation Module 에서 사용하던 Base에 관련된 것들은 Core Module을 만들어서 이동시켰고,

Activity에 따라서 Module을 나누어 presentation Module에서는 MainActivity 만 존재하게 하였다.

movieSearch는 기존 예제에서 사용하던 영화 검색에 대한 부분이고, move 모듈은 DataStore, AAC Navigation을 사용해 보기 위해 추가한 Activity 가 포함되어있는 모듈이다.

 


이렇게 모듈을 나눠두고 난 후 gradle 에서 의존성을 주입해 주어야 하는데,

이 부분에서 고생을 하다가 Coordinator Pattern을 사용하도록 하였다.

 

고생했던 이유는 Activity 모듈간의 이동이 자유롭지 못하기 때문이다.

 

우선, 각 모듈의 의존성을 한번 확인해 보자.

Core : 참조하고 있는 모듈 없음.
Data : Domain
Domain : 참조하고 있는 모듈 없음.
Move : Core, Data, Domain
MovieSearch : Core, Data, Domain
Presentation : Core, Data, Domain

이렇게 되어있을 때, Activity 간의 이동을 하기 위해서는 move, movieSearch, presentation에서 이동하고자 하는 모듈에 대하여 알고 있어야 한다.

 

그렇다면, 모든 Activity 에서 모든 Activity로 이동이 가능할 경우에는 

Move : Core, Data, Domain, MovieSearch, Presentation
MovieSearch : Core, Data, Domain, Move, Presentation
Presentation : Core, Data, Domain, Move, MovieSearch

이처럼 참조를 하게 되어 상호 참조가 일어나게 된다.

 

그렇다고 Core 에서 화면 간의 이동을 담당하자니, 여기다가 넣어도 똑같이 상호 참조가 되기 때문에 고민 끝에 Ios에서 자주 사용하는 방식인 Coordinator Pattern으로 화면 이동을 구성하도록 하였다.

 

이와 같은 방법을 사용하여, App Module 을 Presentation Module로 생각하고 작업을 진행하였다.

 

Presentation 모듈의 gradle 이다.

이동 가능한 모듈 전체를 한 곳에서 참조 가능하도록 해두고, 모든 모듈은 해당 모듈을 통해서만 화면을 이동시키는 방식이다.

Core 모듈에 화면 이동에 관련한 Interface와 호출부를 만들어 두고, 해당 Interface의 구현부를 Presentation 모듈에서 구현하여 이동을 요청하는 모듈에서는 core 모듈만 알고 있어도 되는 것이다.

 

 

이처럼 사용 시에는 Core 단에 선언되어있는 Navigation을 호출하게 되는 것이고, 실제로 구현이 되어있는 Coordinator를 통해 화면 이동이 되는 것이다.

 

 

구현 부도 별 다른 것 없이, 단순히 StartActivity 만 해주도록 해두었다.

Initializer()을 사용하여 startActivity를 시킨 부분을 볼 수 있는데, 그것은 다른 모듈의 참조를 하나의 클래스로만 한정 짓기 위해서 만든 부분이다.

다른 모듈을 참조할 때, 무분별하게 참조하여 사용하는 경우 발생하는 다양한 문제점을 사전에 차단하기 위하여 다른 모듈을 사용할 때는 해당 클래스만 사용하도록 구현한 것이다.


 

Core 모듈에 구현한 전체 클래스이다.

 

위에서 언급한 Coordinator Pattern을 위한 Navigation, 모든 곳에서 사용할 가능성이 있는 Util, 그리고 Base 클래스들을 Core 모듈에 구현해두었다.

이곳에서 조금 더 컴팩트하게 Core 모듈을 구현하고 싶다면, Util 패키지에서 일부를 제거하여 필요한 모듈에서 사용하면 되지 않을까 싶다.

 

 

Presentation 모듈에 구현된 부분이다.

화면간의 이동에 사용하는 Coordinator, DI를 위한 모듈, 그리고 Activity 와 VM 이다.

라이브러리 모듈이 아닌, 애플리케이션 모듈이기 때문에 앱을 실행시키고 기본 세팅에 필요한 것들을 이곳에 넣어두었다.

 

이 두 모듈을 제외하고는 기존 클린 아키텍처 예제에서 다른 부분은 없다.

각 Move, MovieSearch 모듈의 경우 해당 View 에 대한 클래스와, Coordinator 에서 호출하는 initializer 만 존재하고 있기 때문에 이 두 모듈에 대해서는 하단의 gitHub 에서 확인하길 바란다.


Modular Architecture 라고 했지만, 사실 클린 아키텍처 구조를 조금 더 많이, 디테일하게 나눠둔 구조로 보인다.

즉, 조금 더 좁은 범위에서의 기능에 따라서 모듈을 나누어 두어 이점을 얻는 아키텍처라고 생각한다.

 

이렇게 간단한 예제만 만들어보아도

유지/관리의 용이성,

모듈의 추가/제거의 편리함,

Side effect 를 줄일 수 있을 것 같다고 생각된다.

 

하지만,

프로젝트의 크기가 커지면 커질수록 모듈의 갯수도 상당히 많아질 것이고,

불필요하게 나누어지는 경우도 발생하여 복잡도가 높아지지 않을까 생각한다.

 

따라서, 모듈러 아키텍처를 사용하여 프로젝트를 진행한다면,

프로젝트의 구조 설계 단계에서 확실하게 기준을 잡고 필요에 따라서 모듈로 나눌수 있도록 많은 신경을 써야하지 않을까 싶다.

 

해당 게시글에 사용한 예제는 GitHub 에 올려두었다.

https://github.com/HeeGyeong/ModuleArchitecture

 

GitHub - HeeGyeong/ModuleArchitecture

Contribute to HeeGyeong/ModuleArchitecture development by creating an account on GitHub.

github.com

 

728x90