Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- 코루틴 공식 문서
- Android Compose
- Android Custom View
- 백준
- 스레드 vs 코루틴
- 안드로이드 커스텀 뷰
- hilt
- 코루틴 공식문서
- 백준 2615
- Unsupported metadata version. Check that your Kotlin version is >= 1.0: java.lang.IllegalStateException
- 힐트
- RecyclerView Sticky Header
- AAC ViewModel
- Kotlin Serialization
- power menu
- BOJ
- runCatching
- android orbit
- Sticky Header RecyclerView
- 안드로이드 컴포즈
- Android Compose Navigation
- Hilt 에러
- 안드로이드 무한 스크롤
- viewmodel
- 코틀린 에러 핸들링
- Coroutine
- android compose orbit
- Thread vs Coroutine
- 코루틴
- power menu 라이브러리
Archives
- Today
- Total
Beeeam
Android MVVM 패턴 본문
MVVM 패턴
앞에서 포스팅한 MVP 패턴은 View와 Presenter가 1:1 관계라서 View가 추가되면 Presenter도 추가 되야 하는 단점이 있었다. 이러한 단점을 보완한 패턴이 MVVM 패턴이다.
MVVM 패턴은 Model, View, ViewModel로 구성이 된다.
Model과 View는 기존의 패턴들과 동일하고, Presenter 대신에 ViewModel이 사용 된다.
MVVM 패턴도 View가 입력을 받고 해당 요청을 ViewModel로 전달한다. 그러면 그에 맞는 데이터를 Model로 부터 받아온다. 받아온 데이터는 ViewModel에 Livedata에 저장을 한다.
View는 ViewModel에 저장된 Livedata를 관찰하다가 데이터가 변경되면 이를 감지하고, UI를 갱신한다.
MVP와 차이점
Presenter 대신에 ViewModel이 사용된다는 큰 차이점이 있다.
ViewModel?
view와 model의 사이에 있는 요소로 이름의 뜻 그대로 view를 위한 model이다.
view가 관찰(observe) 하고 있기 때문에 관찰 가능한 형태인 Livedata를 사용 해야 한다.
장점
- View와 ViewModel이 1:n 연결되기 때문에 MVP패턴 처럼 Presenter를 많이 생성하지 않아도 된다.
- 데이터를 ViewModel을 통해서 참조하기 때문에 Activity / Fragment의 생명주기에 영향을 받지 않는다. (데이터를 ViewModel이 가지고 있기 때문)
단점
- 규모가 작은 프로젝트에서는 굳이 적용을 안해도 될 듯
- 구조가 복잡해서 진입 장벽이 높다.
적용 예시
Model (Data.kt)
data class Data(
val usrName: String? = null,
val usrPassword: String? = null
) {
fun login(usrName: String?, usrPassword: String?): String {
return if (usrName == "abc" && usrPassword == "1234") {
"성공..!"
} else {
"실패..."
}
}
}
View (MainActivity.kt)
class MainActivity : AppCompatActivity() {
private val viewModel: MainViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val edtId = findViewById<EditText>(R.id.edt_id)
val edtPassword = findViewById<EditText>(R.id.edt_password)
val btnLogin = findViewById<Button>(R.id.btn_login)
val tvResult = findViewById<TextView>(R.id.tv_result)
btnLogin.setOnClickListener {
viewModel.loadResult(edtId.text.toString(), edtPassword.text.toString())
}
viewModel.loginStatus.observe(this) {
tvResult.text = it.toString()
}
}
}
ViewModel (MainViewModel.kt)
class MainViewModel: ViewModel() {
private val data = Data()
private val _loginStatus = MutableLiveData<String>()
val loginStatus: LiveData<String> = _loginStatus
fun loadResult(usrId: String, usrPasswd: String) {
if (usrId != null && usrPasswd != null) {
val res: String = data.login(usrId, usrPasswd)
res?.let { res ->
_loginStatus.value = res
}
}
}
}
ViewModel의 데이터는 View가 관찰할 수 있게 하기 위해서 Livedata를 사용해야 하는데 Livedata는 immutable 속성이라서 MutableLiveData에 model로 부터 받아온 데이터를 저장하고, 이를 Livedata에 저장한다.
'Android' 카테고리의 다른 글
의존성과 의존성 주입(DI) + Hilt란? (0) | 2023.04.07 |
---|---|
Android Hilt 에러 (Unsupported metadata version. Check that your Kotlin version is >= 1.0: java.lang.IllegalStateException) (0) | 2023.04.06 |
Android MVP 패턴 (0) | 2023.03.15 |
Android MVC 패턴 (0) | 2023.03.09 |
App Architecture (0) | 2023.02.27 |