안녕하세요!
이번 글에서는 MVVM(Model-View-ViewModel) 패턴에 대해 자세히 알아보겠습니다.
MVVM 패턴은 MVC, MVP 패턴의 단점을 보완하고 UI와 비즈니스 로직을 분리하는데 중점을 둡니다.
이제 MVVM 패턴의 개념, MVC, MVP 패턴과 비교해서 어떤 점이 보완되었는지,
MVVM 패턴의 이해, MVVM 패턴의 장단점까지 살펴보겠습니다.
MVVM 패턴이란?
MVVM 패턴은 Mode, View, ViewModel 세 가지 구성 요소를 가지는 디자인 패턴입니다.
각 구성 요소는 특정한 역할을 담당하고 서로 독립적으로 동작할 수 있도록 설계되었습니다.
1. 뷰 : View
사용자 인터페이스를 담당합니다.
사용자에게 입력을 뷰모델에게 전달하고, 데이터 바인딩을 통해 뷰모델 데이터가 화면에 자동으로 반영됩니다.
2. 모델 : Model
데이터를 관리, 데이터 관련 비즈니스 로직을 처리합니다.
3. 뷰모델 : ViewModel
뷰와 모델을 연결하는 중간 관리자 역할을 합니다.
사용자 입력을 처리하고 모델과 간접적인 상호 작용을 합니다. 그리고 뷰와 데이터 바인딩을 통해 데이터가 변경될 때 뷰에게 알려줍니다.
MVC vs MVP vs MVVM
MVC 패턴 (자세히 보기)
- 처리방식이 직관적입니다.
- 뷰와 모델 간의 의존성 높습니다. (직접적인 참조)
- 컨트롤러(Activity, Fragment) 역할의 모호성이 있습니다.
MVP 패턴 (자세히 보기)
- 뷰와 모델 간의 의존성 없습니다. (간접적인 참조)
- 프리젠터를 통해 역할의 모호성이 해결되었습니다.
- 뷰와 프리젠터 간에 의존성이 높습니다.
MVVM 패턴
MVVM 패턴은 뷰와 비즈니스 로직을 명확히 분리하기 위해 데이터 바인딩과 LiveData를 활용합니다. 이로 인해 뷰와 모델 간의 의존성은 없고, 뷰와 뷰모델 간의 의존성도 낮아져 모듈화, 재사용성, 유지보수성, 가독성이 향상됩니다. LiveData는 수명 주기를 인식하는 데이터 홀더 클래스로, 데이터 변경 시 활성 상태의 관찰자에게만 알림을 보내 메모리 누수를 방지하고 데이터 일관성을 유지할 수 있습니다.
MVVM 패턴 이해 (+예제)
간단한 예제를 통해 MVVM 코드를 살펴보면 조금 더 이해에 도움이 됩니다.
MainActivity, MainViewModel, MainModel 각자의 역할과 어떻게 상호작용을 하고 있는지 살펴보도록 하겠습니다.
1. 뷰 : MainActivity
데이터 바인딩을 통해 뷰모델과 뷰를 연결합니다.
사용자 입력을 뷰모델로 전달하고, 뷰모델의 데이터를 자동으로 업데이트합니다.
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private val mainViewModel = MainViewModel()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.viewModel = mainViewModel // ViewModel을 바인딩에 연결
binding.lifecycleOwner = this // 데이터 바인딩에 LifecycleOwner 연결
}
}
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="viewModel"
type="com.example.designpatternex.MainViewModel" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/tvResult"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewModel.model.toString()}" />
<Button
android:id="@+id/btnUpdate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{() -> viewModel.update()}"
android:text="UPDATE" />
<Button
android:id="@+id/btnReset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{() -> viewModel.reset()}"
android:text="RESET" />
</LinearLayout>
</layout>
2. 모델 : MainModel
데이터 관리 및 데이터 관련 비즈니스 로직을 처리합니다.
data class MainModel(var name: String, var value: Int) {
fun update(name: String, value: Int) {
this.name = name
this.value = value
}
fun reset() {
this.name = ""
this.value = 0
}
}
3. 뷰모델 : MainViewModel
뷰와 모델을 연결하는 중간관리자 역할을 합니다.
뷰모델은 모든 비즈니스 로직을 수행하며,
뷰와는 데이터 바인딩을 통해 변경된 데이터를 알려주고 모델과는 LiveData를 통해 간접적으로 상호작용을 합니다.
class MainViewModel: ViewModel() {
private val _model = MutableLiveData(MainModel("A", 1))
val model: LiveData<MainModel> get() = _model
fun update() {
_model.value?.update("B", 2)
_model.value = _model.value
}
fun reset() {
_model.value?.reset()
_model.value = _model.value
}
}
MVVM 패턴 장단점
MVVM 패턴 장점
- 데이터 바인딩을 통해 뷰와 뷰모델 간의 의존성이 낮습니다.
- 뷰와 모델 간의 의존성이 없고, 뷰와 뷰모델 간의 의존성도 낮습니다.
MVVM 패턴 단점
- 학습 곡선이 높다.
- 초기 설정이 다소 복잡하다.
결론
MVVM 패턴은 현대 애플리케이션 개발에서 뷰와 비즈니스 로직을 명확하게 분리하고 유지보수성을 높이는 데 중요한 역할을 합니다. 데이터 바인딩과 LiveData를 활용하여 뷰와 뷰모델 간의 의존성을 낮추고, 뷰와 모델 간의 의존성을 없애어 모듈화와 재사용성을 크게 향상할 수 있습니다. 그러나 학습 곡선이 높고 초기 설정이 복잡할 수 있으므로 이를 염두에 두고 프로젝트에 적절하게 사용해야 합니다.
관련 글
참고자료
'안드로이드 > 디자인 패턴' 카테고리의 다른 글
코틀린 싱글톤 패턴: 어떤 방법이 좋을까? (0) | 2024.06.13 |
---|---|
안드로이드 디자인 패턴 : MVP 완벽 정리 (0) | 2024.05.25 |
안드로이드 디자인 패턴: MVC 패턴 완벽 정리 (0) | 2024.05.24 |
댓글