-
Presentation 레이어란?Clean Architecture 2025. 8. 17. 21:46
안녕하세요~ 여러분은 MBTI가 어떻게 되시나요? 저는 INTJ인데요. I를 제외하면 N성향이 제일 강하고, J는 노력형에 가까워요. T는 예전엔 그렇게 많이 높진 않다고 생각했는데 대학교 전공도 그렇고, 개발 공부가 꽤 영향을 주는 것 같아요. 참고로 전 F성향의 사람을 좋아해요. 가장 좋아하는 MBTI는 ENFP, INFJ고 그 다음으로 좋아하는 MBTI는 ESFP, ISFJ에요. 제일 존경하는 MBTI는 ESFJ구요🫠 본론으로 넘어가서 오늘은 안드로이드 클린 아키텍처의 Presentation 레이어에 대해서 알아보겠습니다!
출처: https://github.com/bufferapp/clean-architecture-components-boilerplate?tab=readme-ov-file#Architecture (뷰모델만 그림) 1. Presentation layer의 역할
프레젠테이션 레이어는 UI 레이어와 도메인 레이어 사이에 존재하는데요. 도메인 레이어의 UseCase를 사용하여 데이터를 가져와 UI 레이어로 전달하거나, 반대로 UI의 사용자 액션(버튼 클릭 등)을 처리해서 도메인 레이어에 전달하는 중간다리 역할을 한다고 보시면 됩니다!
2. Presentation layer의 뷰모델
프레젠테이션 레이어에는 Model과 Model Mapper도 있지만, 뷰모델(ViewModel) 역할이 큰데요. 주로 MVVM 패턴의 뷰모델이 사용됩니다. 먼저 관련 코드를 한번 보겠습니다.
class UserViewModel(): ViewModel( private val getUserUseCase: GetUserUseCase ) { private val _user = MutableLiveData<User>() val user: LiveData<User> get() = _user fun getUser(userId: String) { viewModelScope.launch { _user.value = getUserUseCase.invoke(userId) } } }
뷰모델은 UI의 데이터를 상태로 관리하기 위해 위와 같이 LiveData나 StateFlow를 사용합니다. LiveData는 안드로이드 플랫폼에 의존하고, StateFlow는 코틀린에 의존합니다. 근데, Presentation 레이어는 최대한 안드로이드 플랫폼에 의존하지 않는 것을 목표로 하기 때문에 기존에 LiveData를 사용한다면 StateFlow로 바꾸는 것이 좋습니다. 또한, 데이터를 가져오기위해 도메인 레이어의 비즈니스 로직인 UseCase를 호출하는데요. UseCase로부터 얻어온 데이터를 UI 레이어에 전달하여 사용자의 액션을 처리합니다. 이때 데이터가 없는 경우 에러를 전달합니다. 반대로, UI 레이어의 사용자 액션을 받아와 처리한 후 UseCase에 전달하기도 합니다.
3. 클린 아키텍처의 뷰모델 vs AAC ViewModel
클린 아키텍처의 뷰모델은 안드로이드 앱 아키텍처에 기반한 뷰모델과 다른 개념입니다. 왜냐하면, 클린 아키텍처의 뷰모델은 안드로이드 플랫폼을 의존하지 않기 때문입니다. import android.* 와 같은 android 패키지를 사용해서는 안되며, R.id. 또는 R.layout. 처럼 android에 특화된 R도 사용할 수 없습니다. 아까 상태 관리에서 안드로이드에 의존하는 LiveData가 아닌 StateFlow 사용을 권장하는 것도 같은 맥락입니다.
하지만, 이것은 이론상이지 실제 프로젝트에서는 안드로이드의 앱 아키텍처의 뷰모델을 사용할 수 밖에 없습니다. 왜냐하면, 생명주기나 상태관리를 안드로이드 뷰모델이 더 잘 관리해주기 때문입니다. 예를 들어, 화면 회전 등으로 다시 UI가 그려지는 상황에서도 뷰모델 덕분에 데이터 상태가 초기화되지 않고 그대로 유지됩니다. 또한, 뷰모델의 생명주기는 뷰(액티비티, 프래그먼트)의 생명주기보다 더 오래 유지되는 특성이 있습니다.
따라서, 안드로이드 뷰 모델을 사용해야 하기에 AAC 관련한 import android.arch.xxx 는 필요합니다(이때, arch는 architecture을 의미합니다). 하지만 그 외의 다른 안드로이드 패키지는 사용할 수 없습니다.
4. 단방향 데이터 흐름(UDF)
Presentaion 레이어의 뷰모델은 Domain 레이어의 데이터를 UI 에 전달하거나 사용자 액션을 뷰모델에서 처리해서 다시 UseCase에 전달하는 단방향 흐름을 갖습니다.
5. 테스트 코드 작성 예시
class UserViewModelTest { private lateinit var viewModel: UserViewModel private val getUserUseCase = mock(GetUserUseCase::class.java) @Before fun setup() { viewModel = UserViewModel(getUserUseCase) } @Test fun 'test mothod'() { val user = User("1", "홍길동", "대한민국") 'when'(getUserUseCase("1")).thenReturn(user) viewModel.loadUser("1") assertEquals(viewModel.user.value.address, "대한민국") } }
위와 같이 JUnit와 Mockito를 사용하여 ViewModel 단위 테스트를 할 수 있습니다. 실제 UseCase 대신 mock을 주입하여 UserViewModel.loadUser() 메소드가 GetUserUseCase 의 반환값을 LiveData에 올바르게 반영하는지 확인합니다.
오늘은 Presentation 레이어의 뷰모델에 대해 집중적으로 알아보았습니다. 다음에는 Presentation 레이어에 사용자의 액션을 전달하는 UI 레이어에 대해서 알아보겠습니다!
'Clean Architecture' 카테고리의 다른 글
SOLID - SRP (단일 책임 원칙) (0) 2025.10.05 UI 레이어란? (3) 2025.08.24 Local 레이어란? (4) 2025.08.10 Remote 레이어란? (6) 2025.08.03 Data 레이어란? (2) 2025.07.27