← Назад к вопросам

Как MVVM используется в Jetpack Compose

1.0 Junior🔥 132 комментариев
#UI и вёрстка

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

MVVM в Jetpack Compose: Современная архитектура UI

В современной разработке Android с использованием Jetpack Compose, паттерн Model-View-ViewModel (MVVM) остается одним из ключевых архитектурных подходов, хотя его реализация адаптируется к декларативной парадигме Compose. Основная идея — разделение ответственности: ViewModel управляет данными и бизнес-логикой, Compose UI (View) отображает состояние, а Model представляет данные приложения.

Ключевые изменения в реализации MVVM с Compose

В отличие от традиционного View (Activity/Fragment), который был активным контроллером, Compose UI является пассивной, декларативной функцией, реагирующей на изменения состояния. Это меняет взаимодействие между компонентами:

  1. ViewModel становится единственным источником состояния (SSOT) для UI. Он хранит и управляет всем состоянием, которое должно отображаться.
  2. Compose функции читают состояние из ViewModel и преобразуют его в UI. Они не должны напрямую изменять состояние — только отправлять события (например, пользовательские действия) в ViewModel.
  3. Связь осуществляется через реактивные потоки данных, чаще всего через StateFlow или LiveData из Jetpack ViewModel, которые наблюдаются внутри Compose.

Практическая реализация: пример кода

Рассмотрим простой пример счетчика.

ViewModel (хранит состояние и логику)

class CounterViewModel : ViewModel() {
    // Состояние, которое наблюдается UI
    private val _count = MutableStateFlow(0)
    val count: StateFlow<Int> = _count.asStateFlow()

    // События от UI (бизнес-логика)
    fun increment() {
        _count.value += 1
    }

    fun decrement() {
        _count.value -= 1
    }
}

Композиция (UI) в Compose

@Composable
fun CounterScreen(viewModel: CounterViewModel = viewModel()) {
    // Чтение состояния из ViewModel. Коллбэк `collectAsState` автоматически
    // делает recomposition при изменении StateFlow.
    val countState by viewModel.count.collectAsState()

    Column(
        modifier = Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text(text = "Count: $countState", fontSize = 24.sp)
        
        Button(onClick = { viewModel.increment() }) {
            Text("Increment")
        }
        
        Button(onClick = { viewModel.decrement() }) {
            Text("Decrement")
        }
    }
}

Критические принципы и преимущества

  • Односторонний поток данных (Unidirectional Data Flow): UI отправляет события (onClick) в ViewModel → ViewModel обрабатывает логику и обновляет свое состояние → новое состояние автоматически передается в UI через StateFlow/LiveData → Compose перекомпозирует соответствующие части. Это делает поведение предсказуемым и упрощает тестирование.
  • ViewModel survives configuration changes: Использование viewModel() из androidx.lifecycle.viewmodel.compose гарантирует, что состояние не потеряется при пересоздании активности.
  • Compose UI полностью отделена от бизнес-логики: Функции @Composable содержат только код, связанный с отображением. Они становятся более простыми, повторно используемыми и легкими для тестирования в изоляции.
  • Интеграция с другими компонентами Jetpack: ViewModel часто выступает как координатор между Compose UI и другими слоями, такими как Repository (для данных), Use Cases (для логики) или Room Database.

Заключение

В Jetpack Compose MVVM реализуется более "чисто" благодаря декларативной модели. ViewModel сосредотачивается на state management и event handling, а Compose — на declarative rendering. Эта комбинация обеспечивает масштабируемость, поддерживаемость и тестируемость современных Android приложений. Ключевой инструмент — StateFlow в ViewModel и функции типа collectAsState() в Compose для создания реактивной, автоматической связи между ними.

Как MVVM используется в Jetpack Compose | PrepBro