안드로이드

Maverick - MVI Framework 톺아보기

Zibro 2025. 1. 14. 21:59
728x90
반응형

Mavericks - MVI Framework

  • 개별적인 상태 속성을 노출하는 대신, 하나의 불변 데이터 클래스를 사용해 뷰모델을 업데이트하고 UI를 렌더링 합니다.
  • Airbnb 오픈소스로 만든 MVI 프레임워크로 상태관리를 쉽게 처리하기 위한 솔루션을 제공합니다.
  • Mavericks 1.0은 RxJava 기반으로 되어 있었는데, 2.0에서 Coroutines으로 새롭게 작성되었습니다.

Mavericks 2.0에서 추가된 기능

1. Coroutines 사용

  • RxJava에서 Coroutines로 전환되면서 더 간결하고 직관적인 비동기 코드 작성 가능.

2. execute 개선

  • 비동기 작업의 상태를 쉽게 관리할 수 있는 기능

3. Flow 지원

  • Mavericks StateFlow와 함께 작동하며 상태 기반 데이터 스트림을 쉽게 관리할 수 있습니다.

 

 

MVI란?

  • Model : 상태를 나타낸다. MVI에서 Model은 데이터 플로우가 단방향으로 이루어지기 위해 불변성을 보장해야 한다.
  • View - View는 Activity / Fragment를 나타내며, 상태를 전달받아 화면에 렌더링 한다.
  • Intent - 앱 / 사용자가 취하는 행위를 나타내기 위한 의도. View는 Intent를 받고, ViewModel은 intent를 관찰하여 Model을 새로운 상태를 변환합니다.

 

Mavericks를 구성하는 핵심 개념 3가지

`MavericksState`, `MavericksViewModel` , `MavericksView` 

MavericksState
State라고 표시해 주는 Interface으로, 상속받은 클래스에서는 화면에 필요한 정보들을 가지고 있습니다. 

  • Thread Safe
  • 가지고 있는 정보를 바탕으로 UI를 그리게 됨(render)
  • kotlin data class
  • immutable properties
  • 초기 상태를 전달하기 위한 default value를 가지고 있음
data class UserState(
	val name : String = "사용자",
	val age : Int = 27,
	val regionName : String = "역삼1동",
	val profileImageUrl : String? = null
) : MavericksState {
	val introduction : Stirng
		get() = "이름: $name, 나이: $age, 사는 곳: $regionName"
}
반응형



MavericksViewModel

  • 화면 회전 / LMK 등의 Configuration Changes가 발생할 때, 데이터를 유지하기 위해 `Jetpack ViewMdoel`을 구현하는 형태로 사용하고 있습니다.
  • 하나의 Immutable Data Class를 가지고 하나의 data class만 업데이트하고 UI를 렌더링
  • 상태(MavericksSate) 업데이트
  • stateFlow를 사용해서 stream으로 상태를 구독할 수 있는 메서드 제공
class UserViewModel(
	initialState : UserState,
	private val userRepository : UserRepository,
	private val regionRepository : RegionRepository
) : MavericksViewModel<UserState>(initialState) {

	companion object : MavericksViewModelFactory<UserViewModel, UserState>. {
		override fun initialState(viewModelContext : ViewModelContext) : MyState {
			return MyState(...)
		}
		override fun create(viewModelContext: ViewModelContext, state: MyState) : MyViewModel {
			return MyViewModle(state, ...)
		}
	}
}

 

 

MavericksView

실제로 데이터를 렌더링 하는 곳입니다.

  • ViewModel delegates를 통해 MavericksViewModel에 접근할 수 있습니다.
  • invalidate() 메서드를 Override 합니다. 상태 변경 시 UI를 다시 그리는 데 사용됩니다.
  • withState() 메서드를 사용해 state observer를 구현하고, 이를 기반으로 UI를 업데이트합니다.
  • withState() 메서드는 단일 ViewModel에서 ViewModel의 상태에 동기적으로 접근하고 block의 결과를 반환합니다.
class UserFragment : Fragment(), MavericksView {
    private val viewModel: UserViewModel by fragmentViewModel()

    override fun invalidate() = withState(viewModel) { state ->
        binding.nameTextView.text = state.name
        binding.regionTextView.text = state.regionName
        binding.profileImageView.load(state.profileImageUrl)
    }
}
728x90

 

728x90
반응형