
💡 디자인 패턴을 적용하지 않고 개발을 하게 된다면, 액티비티가 무거워지거나 종속성이 너무 강해져 테스트가 힘들고 유지보수가 어려워짐

애플리케이션 구조를 모델, 뷰, 컨트롤러 세 가지 주요 측면으로 관심사를 분리함

애플리케이션 구조를 모델, 뷰, 프리젠터 세 가지 주요 측면으로 관심사를 분리함
사용자가 뷰를 통해 어떤 이벤트를 일으키면 프리젠터가 모델에 접근해서 뷰 대신 데이터를 가져다줌 -> 뷰는 이 데이터를 통해 UI를 업데이트함
interface ViewActionContract {
fun updateUI(message: String)
fun getUserInformation()
}
// 뷰마다 프리젠터를 따로 만들어줘야 함
class ViewActionPresenter(
private val context: Context
): ViewActionContract {
override fun updateUI(message: String) {
Toast.makeText(context, "updateUI() 호출. message : $message", Toast.LENGTH_SHORT).show()
}
override fun getUserInformation() {
Toast.makeText(context, "getUserInformation() 호출", Toast.LENGTH_SHORT).show()
}
}
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".mvp.ViewActionActivity">
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="버튼"
android:layout_marginBottom="40dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
class ViewActionActivity : AppCompatActivity() {
private lateinit var presenter: ViewActionPresenter
private val binding: ActivityViewActionBinding by lazy {
ActivityViewActionBinding.inflate(layoutInflater)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
init()
}
private fun init() {
presenter = ViewActionPresenter(this)
presenter.getUserInformation()
binding.run {
button.setOnClickListener { // 1) 뷰 내부 버튼 클릭하면
presenter.updateUI("호출") // 2) 프리젠터 내부 함수 호출
}
}
}
}

애플리케이션 구조를 모델(Repository, DB), 뷰, 뷰 모델 세 가지 주요 측면으로 관심사를 분리함
View Model은 생명주기로부터 안전하여 메모리 누수를 방지할 수 있음
* 액티비티가 화면의 회전으로 인해 소멸되었다가 다시 생성되어도 뷰 모델은 소멸되지 않고 그대로 유지됨

View와 View Model 사이의 결합도를 느슨하게 하여 유닛테스트가 수월함
View는 View Model을 알지만 View Model은 View를 알지 못하고, View Model은 Model을 알지만 Model은 View Model을 알지 못함 -> 한쪽 방향으로만 의존 관계가 있어서 각 모듈별로 분리하여 개발할 수 있음


도서 '아키텍처를 알아야 앱 개발이 보인다 : Dagger2, Jetpack, RxJava를 통한 안드로이드 클린 코드 설계'
https://bj-turtle.tistory.com/106
https://salix97.tistory.com/205
https://onlyfor-me-blog.tistory.com/554
https://velog.io/@changhee09/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-ViewModel