MVVMパターンとは?
MVVMの概要
MVVM(Model-View-ViewModel)パターンは、Androidアプリ開発においてデータとUIの分離を実現するための設計パターンです。このパターンを利用することで、アプリの保守性や拡張性が向上します。
MVVMは以下の3つの要素で構成されます:
- Model(モデル): アプリのデータやビジネスロジックを管理する。
- View(ビュー): UIを担当し、ユーザーの入力を受け取る。
- ViewModel(ビューモデル): ViewとModelの仲介役となり、UIの状態を管理する。
Jetpack ComposeとViewModelを組み合わせることで、MVVMパターンを簡潔に実装できます。
ViewModelの基本
ViewModelとは?
ViewModelは、画面のライフサイクルを超えてデータを保持し、UIの状態を管理するためのクラスです。Jetpack Composeでは、remember
とmutableStateOf
を使ってUIの状態を管理することもできますが、よりスケーラブルなアプローチとしてViewModelを利用するのが一般的です。
ViewModelの実装
ViewModelはViewModel
クラスを継承して作成します。
class CounterViewModel : ViewModel() {
private var _count = mutableStateOf(0)
val count: State<Int> = _count
fun increment() {
_count.value++
}
}
このViewModelでは、mutableStateOf
を使ってカウントの状態を管理し、increment()
関数で値を更新します。
ComposeとViewModelの連携
ViewModelのインスタンス取得
Jetpack Composeでは、viewModel()
を使ってViewModelのインスタンスを取得できます。
@Composable
fun CounterScreen(viewModel: CounterViewModel = viewModel()) {
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = "カウント: ${viewModel.count.value}", fontSize = 24.sp)
Button(onClick = { viewModel.increment() }) {
Text("増加")
}
}
}
このコードでは、viewModel()
を使ってCounterViewModel
のインスタンスを取得し、その状態をText
コンポーネントに表示しながら、Button
をクリックすることで値を更新しています。
ViewModelとStateの最適な管理
Stateの管理方法
ComposeとViewModelを連携させる際には、状態を適切に管理することが重要です。LiveData
やStateFlow
を使用すると、状態の更新をより効率的に管理できます。
LiveDataの利用
class CounterViewModel : ViewModel() {
private val _count = MutableLiveData(0)
val count: LiveData<Int> = _count
fun increment() {
_count.value = (_count.value ?: 0) + 1
}
}
Compose内でLiveData
を監視するには、observeAsState()
を使用します。
@Composable
fun CounterScreen(viewModel: CounterViewModel = viewModel()) {
val count by viewModel.count.observeAsState(0)
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = "カウント: $count", fontSize = 24.sp)
Button(onClick = { viewModel.increment() }) {
Text("増加")
}
}
}
StateFlowの利用
StateFlow
を使用する場合は、以下のように実装します。
class CounterViewModel : ViewModel() {
private val _count = MutableStateFlow(0)
val count: StateFlow<Int> = _count.asStateFlow()
fun increment() {
_count.value++
}
}
Compose側では、collectAsState()
を使って状態を監視します。
@Composable
fun CounterScreen(viewModel: CounterViewModel = viewModel()) {
val count by viewModel.count.collectAsState()
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = "カウント: $count", fontSize = 24.sp)
Button(onClick = { viewModel.increment() }) {
Text("増加")
}
}
}
ViewModelとリポジトリパターンの組み合わせ
リポジトリパターンとは?
リポジトリパターンを導入することで、データ取得の責務をViewModelから分離し、より保守しやすいアーキテクチャを実現できます。
class CounterRepository {
private val _count = MutableStateFlow(0)
val count: StateFlow<Int> get() = _count
fun increment() {
_count.value++
}
}
ViewModelではリポジトリを利用して状態を管理します。
class CounterViewModel(private val repository: CounterRepository) : ViewModel() {
val count: StateFlow<Int> = repository.count
fun increment() {
repository.increment()
}
}
まとめ
- MVVMパターンは、データとUIの分離を目的とした設計パターン。
- ViewModelを利用することで、Composeの状態管理が容易に。
- LiveDataやStateFlowを使うことで、より効率的な状態管理が可能。
- リポジトリパターンを組み合わせると、より拡張性の高いアーキテクチャが構築できる。
Jetpack ComposeとViewModelを適切に組み合わせて、スケーラブルなアプリを開発しましょう!