클린 아키텍처 왜 사용하고 싶은데?
"자주 바뀌는 외부 세계들과 느슨하게 결합하고 싶어 ㅠ-ㅠ"
"관심사 분리를 잘하고 싶어 ㅜ.ㅜ"
그렇다면 "클린 아키텍처 " 어때?
"클린 아키텍처를 사용하게 되면 간단한 로직을 구현할 때도 많은 컴포넌트를 구현해야 하잖아!!"
"맞아, 맞아. 생성하는 파일의 코드량도 늘어나고.. 그 많은 코드베이스 읽을 생각하면 벌써부터 피로감이 몰려온다고.."
그렇지만 코드베이스의 가독성이라는 게 아키텍처 전반의 일관성과 각 코드 파일의 코드레벨에서의 가독성의 합이 결정하는 게 더 크다고
흠.. 그럼 괜찮은 것 같은데 한번 알아볼까?
클린 아키텍처 사용 시 이점에는 여러가지가 있지만 그중 실제 사용하면서 제일 와닿았던 이점은 세 가지가 가장 와닿았다.
- 앱의 확장성
- 프로젝트의 일관성 부여 -> 협업이 용이해짐
- 레이어 분리가 되어 있어 각 레이어를 독립적으로 개발하고 테스트할 수 있어 개발 효율성이 향상
실제 실무를 겪었을 때 있었던 일이다.
개발 일정이 타이트하게 잡혔지만 UI 디자인이 아직 나오지 않았을 때였다.
클린 아키텍처를 사용하고 있었기 때문에 UI와 비즈니스 로직을 분리해 개발이 가능한 상태였고
비즈니스 로직을 선 개발하고 개발 일정 하루 전에 나온 UI 디자인을 받아 개발을 일정까지 완수할 수 있었다.
그렇다면 안드로이드에서의 클린 아키텍처는 어떤 구조를 가져가야 할까?
(* 안드로이드에서 권장하는 앱 아키텍처 가이드: https://developer.android.com/topic/architecture?hl=ko )
일반적인 아키텍처 원칙에 따라 각 애플리케이션에는 최소한 다음 두 가지 레이어(Ui Layer, Data Layer)가 포함되어야 한다.
*참고로, Domain Layer는 앱 아키텍처에서는 옵셔널(선택적)인 것이지만 클린 아키텍처에서는 useCase라는 비즈니스 로직을 Domain layer에 분리하고 있기 때문에 Domain Layer를 당연하게 사용하고 있다.
- UI Layer
- 화면에 애플리케이션 데이터를 표시
- Data Layer
- 앱의 비즈니스 로직을 포함하고 애플리케이션 데이터를 노출
- Domain Layer(optional)
- UI와 Data Layer간의 상호작용을 간소화하고 재사용
- 복잡한 비즈니스 로직이나 여러 ViewModel에서 재사용되는 간단한 비즈니스 로직의 캡슐화를 담당
- 코드 중복 방지
클린아키텍처의 핵심은 "비즈니스 로직을 바뀔 수 있는 모든 것으로부터 분리하자"
-> 데이터 베이스를 변경할 일이 생겼을 때, 유즈케이스도 함께 바꿔야 한다면 그것은 클린아키텍처에서 가장 중요하게 생각하는 의존성 규칙을 만족하지 않았을 가능성이 매우 높다.
*여기서 잠깐, 기획이 바뀌면 유즈케이스가 바뀔 수도 있지 않나?
-> 맞다. 기획이 바뀌면 기능이 바뀌는 것이기 때문에 유즈케이스가 바뀌는 것은 당연한 것이다. 하지만 그 부분을 이야기하는 게 아닌 데이터 베이스만 변경해야 하는 상황에서 유즈케이스까지 바꿀 일이 생긴다면 의존성 규칙에 대해서 다시 생각해 볼 필요가 있다는 것이다.
의존성 규칙이 뭔데?
이미지 출처: https://yoonseon.tistory.com/163
위 사진 처럼 원의 바깥에서부터 안 쪽으로 향하는 모습이 올바른 모습이고
반대로, 원 안쪽에서 바깥으로 향한다면 그것은 의존성 역전이기 때문에 의존성 법칙에 위배되는 일이다.
즉, 안 쪽 원에서 바깥 쪽 원을 직접적으로 호출할 수 없다.
반드시 인터페이스를 통해 의존성을 주입받아야 하며 원 안쪽으로만 의존성을 가질 수 있다.
예를 들어, 유즈케이스가 프레젠터를 직접적으로 호출해야하는 상황이 있기 마련인데
이때 프리젠터를 유즈케이스가 호출하는 것은 의존성 규칙에 위반된다.
왜냐하면 프리젠터 로직이 수정될 때마다 유즈케이스도 역시 수정이 필요하기 때문이다.
한 줄 요약: 원 바깥에서 안쪽으로만 의존성을 가질 수 있고, 반대로 의존하려고 하는 것은 의존성 규칙에 위반된다!!!!
공식문서에는 위처럼 클린아키텍처에 대한 개념만 나온다.
실제 어떻게 구현했는지에 대해서는 구체적으로 알려주지 않는다.
찾아보면 엉클밥이 자바 코드로 구현한 예시가 있긴 하지만 이것을 안드로이드 컨텍스트로 가지고 오는 게 쉽지 않을 뿐더러 OOP방식을 기반으로 했기 때문에 낯설 게 느껴질 수 있다. 그리고 저 코드는 엉클밥이 2012년에 제안한 것이고 안드로이드에서는 클린아키텍처를 2019년도 쯤부터 다루고 있기 때문에 예전에 제안한 방식보다 좀 더 다르게 구현할 필요가 있다.
클린 아키텍처는 MVP, MVVM 패턴보다 낫다?
-> NO
MVP, MVVM은 프레젠테이션 로직을 어떻게 구현할 것인지를 결정하는 프레젠테이션 패턴이지, 어플리케이션 전체를 조망하는 시스템과는 레벨이 맞지 않다. 그래서 오히려 클린 아키텍처 내부에 프레젠테이션 로직을 MVP or MVVM 패턴으로 구현할 것이다라는 포함관계로서의 표현이 가능할지언정 MVP, MVVM을 클린아키텍처와 비교하는 것은 비교 대상이 맞지 않다고 생각한다.
*프레젠테이션 패턴이란?
프레젠테이션 게층을 여러 부분으로 분리하기 위한 것일 뿐 전체 앱을 여러 부분으로 분리하기 위한 것이 아님
결론
클린 아키텍처에서는 추상적인 방법론을 제시하였을 뿐 무슨 레이어에 무슨 코드를 쓰세요라고 구체적으로 제시한 적이 없다. 엉클밥이 작성한 글을 읽지 않고 블로그에서 주워들었던 내용으로 학습하였을 때는 누군가가 클린 아키텍처가 무엇이냐고 물어보면 기계처럼 UI, Data, Domain 레이어 계층에 대해 설명하곤 했다. 하지만 자세히 들여다보니 엉클밥이 제시한 관심사의 분리, 의존성 규칙에 위반되지 않으면서 UI와 비즈니스 로직이 분리되게 사용한다면 그것이 클린 아키텍처가 아닐까 하는 게 내가 내린 결론이다.

두 줄 요약:
클린 아키텍처는 애플리케이션을 여러 계층으로 나누어 비즈니스 로직과 UI를 분리하고, 의존성 규칙을 통해 유지보수성과 테스트 용이성을 높이는 소프트웨어 설계 원칙이다.
엉클밥이 제시한 클린 아키텍처 원문: https://blog.cleancoder.com/uncle-bob/2011/11/22/Clean-Architecture.html 2019 드로이드 나이츠 클린아키텍처 강의 자료: https://speakerdeck.com/sunghyunzz/clean-architecture-in-android-revised 2019 드로이드 나이츠 클린 아키텍처 강의 영상: https://youtu.be/5eOYb0Yvqh0?si=CKB-o19lRhXjD2NU * 본 글은 엉클밥 공식 문서와 2019 드로이드 나이츠 클린아키텍처 강연 내용을 바탕으로 정리해 본 글입니다. |
'android' 카테고리의 다른 글
startActivityForResult 너 누군데. ActivityResultLauncher를 써야 하는 이유 (2) | 2024.09.25 |
---|---|
[Android] DI를 사용해보자 | Hilt (3) | 2024.09.05 |
[Android] Serializable VS Parcelable (5) | 2024.08.28 |
[Android] 안드로이드를 한다면 꼭 알아야 하는 개념 | 동기, 비동기 (0) | 2024.08.25 |
API 서버 전송 실패 시 Firebase Crashlytics로 log 남기기 (0) | 2024.08.16 |