
Android 기본적인 컴포넌트들에 대해 공부하고 여러 아키텍처 및 라이브러리에 대해 이론만 공부만 했을 때는 크게 다가오지 않았던 경험이 많았습니다. 이를 해결하기 위해서 프로젝트를 통해서 Android 앱을 개발하였고 꽤 많은 시간이 지났지만 그동안 배웠던 것을 정리해보려고 합니다.
첫 번째 프로젝트는 BuddyCon 입니다. BuddyCon 프로젝트를 시작함에 있어서 어떤 아키텍처를 적용해볼까 했을 때 팀원 모두 클린 아키텍처에 배우고 싶다는 열망이 있었고 처음으로 적용한 내용을 공유해볼까 합니다.

로버트 C.마틴(Robert C.Martin) 이 제안한 소프트웨어 아키텍처로 Clean Architecture는 다양한 분야에서 활용되고 있습니다. 클린 아키텍처는 다음과 같이 두 가지의 관점에서 볼 수 있습니다.
객체지향 5대 원리로 5가지 원칙들을 클린 아키텍처에서는 일목요연하게 정리하고 있습니다.
각 원칙들에 대해서는 많은 블로그에서 자세히 다루고 예제까지 있기 때문에 찾아보시는걸 추천드립니다 :)
계층 분리 원칙이란 위 그림처럼 각 계층의 역할을 이해하고 어떻게 나누고 어떤 요소로 구성할 것인가에 대한 원칙을 알려주는 것입니다.
가운데로 갈 수록 가장 상위의 추상화 규칙이 적용된 고수준 컴포넌트이고 바깥으로 갈 수록 좀 더 구체적인 저수준 컴포넌트입니다. 고수준일수록 핵심적인 비즈니스 로직이 존재하고 외부의 변경으로부터 영향을 받지 않습니다.
- 경계선 (Boundaries) : 계층 구조의 개념이 널리 적용됨
- 유스케이스 (Use Case) : 도메인 계층의 분리로 소스코드 변경 안정성이 높아짐
- 험블 객체 (Humble Object) : 프리젠테이션 계층의 테스트 가능성, 가독성, 유지보수성 향상
- 의존성 역전 (DIP): modular 한 프로젝트 구조의 확산
모바일에서도 클린 아키텍처를 적용하여 여러 부분에 영향을 주었지만 아래 네 가지 부분에서 가장 큰 영향을 주었다고 합니다. 그 중에서도 가장 중요한 영향은 경계에 대한 것으로 모듈의 변경이 다른 모듈에 영향을 주면 안되고 같은 모듈은 일관되도록 계층을 구분하는 것입니다. 즉, 결합도는 낮고 응집도는 높도록 설계를 가져가야만 했습니다.
그 결과로 보편적인 클린 아키텍처의 4개의 경계에서 3개의 계층으로 분리하는 것으로 일반화되었습니다.

화면에 보여지는 단순 View 부터 사용자와 상호작용을 하여 UI 변경하도록 하는 프리젠테이션 로직까지 포함합니다.
Presenter는 단순히 MVP의 프리젠터만을 의미하는 것이 아닌 뷰와 관련된 비즈니스 로직을 처리하는 MVVM에서의 ViewModel도 동일하게 볼 수 있습니다. Presenter나 ViewModel은 플랫폼에 의존하지 않는 클래스로 단위 테스트를 쉽게 구현할 수 있습니다. Android ViewModel은 플랫폼에 의존적인 클래스지만 여기서 말하는 ViewModel과는 다릅니다. 이에 대해 더 공부를 하고 싶다면 MVVM ViewModel과 AAC ViewModel과의 차이를 알아보는 것도 좋을 것 같습니다!
Android 설계에서 가장 중요한 부분이라고 할 수 있는 프리젠테이션 계층을 어떻게 구성할 것인가 고민을 많이 해야합니다. 서비스의 특징에 맞게 MVP, MVVM, MVI 등의 패턴을 적용하고 유지보수성을 높이고 테스트가 용이한 구조로 구현하도록 해야합니다.
- 어떤 경우에도 Model은 분리
- Android에서 발생할 발생할 수 있는 특수한 상황 처리 (Context, 생명주기, 여러 이벤트)
UI 계층에서 사용되기 위한 캡슐화된 비즈니스 로직들을 모아 놓는 계층으로 복잡한 비즈니스 로직이나 UI 계층에서의 재사용성이 높은 로직 캡슐화를 담당합니다.
도메인 계층의 비즈니스 로직 != 프리젠테이션의 비즈니스 로직 != 데이터 계층의 비즈니스 로직
데이터 계층 : 애플리케이션의 데이터 생성, 저장, 변경하는 간단한 비즈니스 로직
프리젠테이션 계층 : UI 관련 비즈니스 로직
도메인 계층 : 복잡한 비즈니스 로직 or 재사용성이 높은 프레젠테이션에서의 UI 관련 비즈니스 로직
UI 계층에서 재사용성이 높은 비즈니스 로직을 도메인 계층으로 옮길 때 엄밀하게는 도메인 로직이라고 할 수 없어서 UI 계층에서 ViewUseCase 을 만들어서 캡슐화를 해도 무방합니다. 그래도 클린 아키텍처 원칙상 비즈니스 레이어를 표현하는건 도메인 레이어라고 알고 계시면 좋을 것 같습니다.
데이터 계층은 애플리케이션 데이터 및 간단한 비즈니스 로직이 포함되는 계층으로 데이터 계층의 비즈니스 로직은 애플리케이션의 데이터 생성, 저장, 변경 방식을 결정하는 규칙으로 구성됩니다.
데이터 계층에서 2가지 중요 패턴이 있습니다.
Repository Pattern
데이터 소스와 애플리케이션 간의 상호작용을 추상화하고, 데이터 소스의 세부사항을 알 필요 없게 해주는 패턴
- 추상화로 로컬, 서버인지 세부사항 알 필요 없이 애플리케이션은 API 사용 가능
- Mock 데이터를 사용하여 데이터 소스 테스트 가능
DataStore Pattern
실제 데이터 처리를 담당하고 데이터 처리의 구현 방식을 감춰줍니다. ex) 로컬 DB를 SQLite에서 Room으로 변경
또한, DataSource는 데이터 출처를 단 한곳으로 제한을 해야합니다. 하나의 데이터 소스가 로컬 데이터나 서버 두 곳 모두에서 가지고 올 수 있게 하면 안됩니다.
Repository : 관점에 따라 도메인 계층 or 데이터 계층, 도메인 계층의 UseCase가 필요로 하는 데이터 저장/수정 등의 기능을 제공하는 클래스
Repository를 테스트 시에 DataSource를 인터페이스 형태로 참고하기 때문에 Mock 을 사용하여 테스트 코드를 작성할 수도 있습니다.
DataSource : 실제 데이터의 입출력 담당
Entity : 데이터 소스에서 사용되는 데이터(클린 아키텍처의 엔티티랑 다름) , REST API의 요청/응답을 위한 JSON, 로컬 DB에 저장하기 위한 테이블 대표적임
안드로이드 아키텍처에 관심이 많으신 분들은 이미 아시겠지만, 구글에서도 아키텍처를 가이드를 하고 있고 여러 문서 및 코드랩을 통해서 설명하고 있습니다. 그리고 유명한 now-in-android 프로젝트를 통해서 구글 권장 아키텍처를 보여주고 있습니다.
하지만, 구글 권장 아키텍처는 클린 아키텍처를 따르지 않고 있고 이 부분에 대해서 많은 논쟁이 있는데 이부분은 아래 글을 참고하시면 좋을 것 같습니다.
https://medium.com/@mangbaam/now-in-android-%EB%8A%94-%ED%81%B4%EB%A6%B0%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98%EC%99%80-solid-%EB%A5%BC-%EB%94%B0%EB%A5%B4%EC%A7%80-%EC%95%8A%EB%8A%94%EB%8B%A4-8f03150529d3

클린 아키텍처에서와 구글 권장 아키텍처의 각 계층별 역할은 매우 동일합니다. 하지만 가장 큰 차이점에서는 Domain Layer 라고 볼 수 있습니다. 클린 아키텍처에서는 도메인 레이어는 필수적으로 적용하여 핵심 비즈니스 로직을 정의하고 비즈니스 로직을 캡슐화를 합니다. 그리고 다양한 프리젠테이션 계층에서 사용할 수 있도록 합니다.
반면, 구글 권장 아키텍처에서는 도메인 레이어는 Optional 로서 강조하고 있습니다. 정말로 복잡성을 처리하거나 재사용성을 선호하는 등 필요한 경우에만 도메인 레이어를 사용하라고 권장하고 있습니다.

위의 미디엄의 이슈 등록으로 인한 도메인 계층에서의 문구가 추가된 것도 확인할 수 있습니다.
클린 아키텍처부터 구글 권장 아키텍처까지 많은 설명을 하게 되었습니다. 결론적으로 BuddyCon은 클린 아키텍처를 적용해보기로 하였습니다. 아키텍처를 선택할 당시에는 구글 권장 아키텍처가 클린 아키텍처라고 생각을 했었고 서비스 시나리오 및 정책도 완료가 되지 않은 상태였었습니다. 그래도 모든 팀원들이 클린 아키텍처를 적용해보고 싶었고 저 또한 이론보다는 적용해봄으로써 장점과 단점을 알 수 있지 않을까 싶어서 선택하게 되었습니다.
적용 방법은 다음 글에서 하나씩 설명하도록 하겠습니다! 프로젝트 링크는 아래 하단에 있습니다~
https://github.com/Team-BuddyCon/ANDROID