728x90
MVVM이란?
MVVM이란 MVC 패턴 특성상 Activity에 모든 코드를 다 집어넣으면서 Activity가 무거워지고 View와 Model 간의 의존성이 높아지며 앱 규모가 커질수록 코드가 복잡해지는 단점을 보완하고자 나온 패턴이다.
MVVM은 Model, View, ViewModel로 구성되어 있다.
View
- Activity/Fragment
- 비지니스 로직을 포함하지 않고 UI와 관련된 로직만 존재
- 유저의 Action을 감지(ex. 버튼 클릭)
- ViewModel을 Observe 하다가 값이 변경되면 해당 값을 처리
ViewModel
- View가 요청한 데이터를 Model에 요청
- Model로부터 요청한 데이터를 받음
- 비지니스 로직만 존재
Model
- 실질적인 Data를 다루는 구성 요소
- ViewModel로부터 데이터를 요청받거나 요청한 데이터를 반환
- 서버 DB, 로컬 DB, Api를 이용
MVVM 흐름
View -> ViewModel -> Repository -> DataSource(Api, Local DB)
구조도에 따라서 구현
구현에 앞서서 Android AAC에 ViewModel이라고 있는데 이는 엄연히 말하자면 MVVM의 ViewModel과는 다른 것이다. 하지만 구글에서 MVVM을 구현할 때 AAC의 ViewModel을 사용하면 생명주기에 맞는 클래스를 구현할 수 있고 데이터를 유지할 수 있도록 제공하기 때문에 사용한다.
예를 들어 A유저가 '내 정보 검색하기'라는 버튼을 클릭한다고 가정해 본다.
- Activity에서 A유저의 클릭 이벤트를 감지한다.
- RemoteDataSource에서 내 정보 검색하기 Api를 호출한다.
- 서버로 부터 받은 A유저 데이터를 ViewModel의 LiveData에 저장한다.
- Activity는 LivceData의 변화를 Observe 하여 UI와 데이터 상태를 동기화한다.
예시의 상황을 아래와 같이 구현해 보았다.(참고로 의존성 주입으로 Hilt를 사용)
- ApiService
interface ApiService {
@GET("user")
suspend fun getUser(id: Long): User
}
- Repository
class MainRepository @Inject constructor(private val apiService: ApiService) {
suspend fun getUser(id: Long) = withContext(Dispatchers.IO) {
return@withContext apiService.getUser(id)
}
}
- ViewModel
@HiltViewModel
class MainViewModel @Inject constructor(private val repository: MainRepository) : ViewModel() {
private val _user = MutableLiveData<User>()
val user: LiveData<User>
get() = _user
fun getUser(id: Long) = viewModelScope.launch {
_user.value = repository.getUser(id)
}
}
- Activity
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
private val viewModel: MainViewModel by viewModels()
private lateinit var dataBinding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
dataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
//유저의 값이 변경될 경우
viewModel.user.observe(this) {
Toast.makeText(this, it.name, Toast.LENGTH_SHORT).show()
}
dataBinding.searchButton.setOnClickListener {
viewModel.userApi(3422)
}
}
}
'Android' 카테고리의 다른 글
이제는 필수가 되어 버린 페이지네이션(Pagination) (0) | 2021.11.17 |
---|---|
디자인 아키텍처 3 - MVC (0) | 2021.11.16 |
Layout xml 그룹 관리 (0) | 2021.11.16 |
디자인 아키텍처 2 - MVP (0) | 2021.11.16 |
CustomView 1 - 이메일 입력창 (0) | 2021.11.16 |