๐Ÿงฉ [Android] MVVM

yeonjeenยท2024๋…„ 5์›” 2์ผ


๋ณธ๊ฒฉ ๋‚ด๊ฐ€ ๊ณต๋ถ€ํ•œ ๊ฑฐ ๋‚ด๊ฐ€ ์ •๋ฆฌํ•˜๊ธฐ๐Ÿ”ฅ


1๏ธโƒฃ MVVM์ด๋ž€?


โœจ Model-View-ViewModel์˜ ์•ฝ์ž๋กœ ์†Œํ”„ํŠธ์›จ์–ด ์•„ํ‚คํ…์ฒ˜ ๋””์ž์ธ ํŒจํ„ด์ด๋‹ค.
View

  • ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค(UI)

Model

  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ฐ์ดํ„ฐ์™€ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ํฌํ•จ
  • ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ณ  ๊ฐ€๊ณตํ•˜๋Š” ์—ญํ• 

ViewMdoel

  • View์™€ Model ์‚ฌ์ด์—์„œ ์ค‘๊ฐœ์ž ์—ญํ• 
  • ๋ฐ์ดํ„ฐ๋ฅผ ์ œ๊ณตํ•˜๊ณ , ๋ทฐ์—์„œ ๋ฐœ์ƒํ•œ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌ
  • UI ์ƒํƒœ ๊ด€๋ฆฌ ๋ฐ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์‹คํ–‰

MVVM์„ '๋””์ž์ธ ํŒจํ„ด'์ด๋ผ๊ณ  ๋ช…์‹œํ•˜๋Š” ๊ฒฝ์šฐ๋„ ์žˆ๊ณ , '์•„ํ‚คํ…์ฒ˜'๋ผ๊ณ  ๋ช…์‹œํ•˜๋Š” ๊ฒฝ์šฐ๋„ ์žˆ๋Š”๋ฐ ์ด์™€ ๊ด€๋ จํ•ด์„œ๋Š” ์•„ํ‚คํ…์ฒ˜ ํŒจํ„ด๊ณผ ๋””์ž์ธํŒจํ„ด์„ ์ฐธ๊ณ ํ•ด๋ณด๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค

2๏ธโƒฃ MVVM ์ ์šฉํ•˜๊ธฐ

โœจ ๋ชจ๋ธ ํด๋ž˜์Šค ์ •์˜ํ•˜๊ธฐ

data class TodoItem(
    val id: Int,
    val title: String,
    val isCompleted: Boolean
)

โœจ ์•กํ‹ฐ๋น„ํ‹ฐ์— ๋ทฐ๋ชจ๋ธ ์ ์šฉํ•˜๊ธฐ

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

    private lateinit var viewModel: TodoListViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // ViewModel ์ดˆ๊ธฐํ™”
        viewModel = ViewModelProvider(this).get(TodoListViewModel::class.java)

        // ViewModel์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€์ฐฐํ•˜๊ณ  UI๋ฅผ ์—…๋ฐ์ดํŠธ
        viewModel.todoItems.observe(this, Observer { todoItems ->
            todoItemsTextView.text = todoItems.joinToString("\n") { it.title }
        })

        // ๋ฐ์ดํ„ฐ ๋กœ๋”ฉ ์š”์ฒญ
        viewModel.fetchTodoItems()
    }
}

โœจ ๋ทฐ๋ชจ๋ธ ๊ตฌํ˜„ํ•˜๊ธฐ

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel

class TodoListViewModel : ViewModel() {

    private val _todoItems = MutableLiveData<List<TodoItem>>()
    val todoItems: LiveData<List<TodoItem>> = _todoItems

    fun fetchTodoItems() {
        // ์‹ค์ œ ๋ฐ์ดํ„ฐ ๋กœ๋”ฉ ๋กœ์ง์€ ์—ฌ๊ธฐ์— ๊ตฌํ˜„๋จ
        val items = listOf(
            TodoItem(1, "Buy groceries", false),
            TodoItem(2, "Walk the dog", true)
        )
        _todoItems.value = items
    }
}

3๏ธโƒฃ MVVM์˜ ์žฅ๋‹จ์ 

๐Ÿ‘๐Ÿป ์žฅ์ 

  • ๋กœ์ง์ด ๋ถ„๋ฆฌ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์œ ์ง€๋ณด์ˆ˜์— ์šฉ์ดํ•˜๋‹ค
  • view๋Š” viewmodel์„ ์•Œ์ง€๋งŒ viewmodel์€ view๋ฅผ ๋ชจ๋ฅธ๋‹ค. ๋˜ํ•œ viewmodel์€ model์„ ํ•˜์ง€๋งŒ model์€ viewmodel์„ ๋ชจ๋ฅธ๋‹ค. ์ฆ‰ ํ•œ์ชฝ ๋ฐฉํ–ฅ์œผ๋กœ๋งŒ ์˜์กด ๊ด€๊ณ„๊ฐ€ ์žˆ์–ด์„œ ๋ชจ๋“ˆ๋ณ„๋กœ ๋ถ„๋ฆฌํ•ด์„œ ๊ฐœ๋ฐœ ํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ‘Ž๐Ÿป ๋‹จ์ 

  • ๋‹ค๋ฅธ ํŒจํ„ด๋ณด๋‹ค ๋ณต์žกํ•˜๊ณ  ์ž‘์€๊ทœ๋ชจ์˜ ํ”„๋กœ์ ํŠธ์ผ ๊ฒฝ์šฐ ๋ฆฌ์†Œ์Šค ๋‚ญ๋น„ ์ผ ์ˆ˜ ์žˆ๋‹ค.
  • Databinding, LiveData ๋“ฑ ๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ•„์ˆ˜์ ์œผ๋กœ ์•Œ์•„์•ผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€