Разработка
Почему ваша ViewModel технически нестабильна — и почему Compose это не волнует
Для монолитных проектов это не является серьёзной проблемой. Поскольку весь код компилируется в одном модуле, оценка стабильности проста. Однако, если вы рассматриваете многомодульную архитектуру и интересуетесь концепциями стабильности Compose, эта статья определённо будет полезна.
Знаете ли вы, что почти все ViewModel нестабильны? Когда мы впервые изучаем Compose, нас учат использовать стабильные классы, а не нестабильные.
Но ViewModel нестабильны. Так почему же никто ничего не говорит, когда мы используем нестабильные ViewModel?
Как Compose определяет стабильность?
Необходимо понимать, как компилятор Compose определяет стабильность.
Класс считается стабильным, если все его члены неизменяемы или имеют типы, которые отслеживаются средой выполнения Compose.
data class Stable(
val a: Int, // Stable
val b: MutableState<Int>, // Stable, Traceable in the Compose runtime
val c: SnapshotStateList<Int> // Stable, Traceable in the Compose runtime
)
data class Unstable(
var b: Int // Unstable
)
data class Runtime(
val i: Interface // Uncertain, compose compiler don't know which implementation will be used at runtime.
)
interface Interface {
data object Impl : Interface
}
Мы можем ожидать, что компилятор определит стабильность следующим образом.
stable class Stable {
stable val a: Int
stable val b: MutableState<Int>
stable val c: SnapshotStateList<Int>
<runtime stability> = Stable
}
unstable class Unstable {
stable var b: Int
<runtime stability> = Unstable
}
runtime class Runtime {
runtime val i: Interface
<runtime stability> = Uncertain(Interface)
}
Однако это определение применяется только в пределах модуля, где объявлен плагин компилятора Compose.
Когда стабильность выходит за рамки модуля
Я продемонстрирую пример создания стабильной модели в слое Данных и её внедрения во ViewModel.

stableModel в слое Данных

viewModel в слое Презентации
Если вы инжектировали в целом стабильный класс, естественно, вы ожидаете, что ViewModel также будет стабильной.
Однако результат таков:
Таким образом, мы видим, что классы, получающие инъекции из других слоёв, также становятся нестабильными.
Почему нестабильные ViewModel допустимы в Compose
ViewModel обычно внедряет Репозиторий или UseCase и она выступает в качестве точки соединения между пользовательским интерфейсом и бизнес-логикой.
class ViewModel(
private val repository: Repository, // from domain or data layer
private val useCase: UseCase // from domain layer
) : ViewModel()
Как мы видели ранее, классы, инжектирующие классы из других уровней, нестабильны.
Следовательно, ViewModel также должен быть нестабильным классом.
Тем не менее, всё ещё остается вопрос: если ViewModel нестабильна, почему она приемлема?
Ответ
Причина проста. Мы не передаём саму ViewModel в композабл объект, мы передаём стабильное состояние внутри ViewModel:
data class TestState(
val data: String
)
@Composable
fun Screen(
viewModel: TestViewModel
) {
val state by viewModel.state.collectAsState()
Child(state)
}
@Composable
fun Child(
state: TestState
) {
Text(state.data)
}
ViewModel обычно создаётся только один раз в компонуемом объекте верхнего уровня и передаётся в качестве аргумента. После этого она собирает управляемое ею состояние и передаёт его дочерним компонуемым объектам. Поэтому, даже если ViewModel нестабильна, это не создаёт проблем.
В заключение
Для монолитных проектов это не является серьёзной проблемой. Поскольку весь код компилируется в одном модуле, оценка стабильности проста. Однако, если вы рассматриваете многомодульную архитектуру и интересуетесь концепциями стабильности Compose, эта статья определённо будет полезна.
-
Аналитика магазинов2 недели назад
Мобильный рынок Ближнего Востока: исследование Bidease и Sensor Tower выявляет драйверы роста
-
Интегрированные среды разработки3 недели назад
Chad: The Brainrot IDE — дикая среда разработки с играми и развлечениями
-
Новости4 недели назад
Видео и подкасты о мобильной разработке 2025.45
-
Новости3 недели назад
Видео и подкасты о мобильной разработке 2025.46


