Ответ
Плюсы:
- Четкое разделение ответственности (UI, бизнес-логика, данные)
- Легче тестировать (ViewModel не зависит от View)
- Поддержка Android Architecture Components (LiveData, ViewModel)
- Автоматическая привязка данных (Data Binding)
Минусы:
- Больше boilerplate-кода (особенно без Data Binding)
- Сложность при работе с одноразовыми событиями (например, навигация)
- ViewModel может разрастаться (нужно дробить на UseCase/Interactor)
Пример с LiveData:
class MyViewModel : ViewModel() {
private val _data = MutableLiveData<String>()
val data: LiveData<String> = _data
fun loadData() {
_data.value = "Hello MVVM"
}
} Ответ 18+ 🔞
Ну, вот смотри, разбираем эту вашу MVVM, как будто это не архитектура, а какой-то новый вид спорта. С одной стороны, всё красиво и по полочкам разложено, а с другой — иногда такое ощущение, что ты не приложение пишешь, а бумажки для бюрократов заполняешь.
Что там хорошего, говоришь? Ну, слушай:
- Разделение, блядь, ответственности. Это главный плюс, ёпта. UI отдельно, бизнес-логика в своей песочнице, данные — сами по себе. Как будто в коммуналке живут, но каждый в своей комнате и не лезет к соседу без стука. Красота.
- Тестировать — одно удовольствие. ViewModel-то у тебя от View не зависит, как собака от блох. Хочешь — юнит-тесты пиши, хочешь — просто в голове проверяй. Главное, что не надо весь этот ёперный театр с активитями и фрагментами на каждый чих поднимать.
- Поддержка от гугла. LiveData, ViewModel — всё это из коробки идёт, не надо велосипеды из говна и палок собирать. Как будто тебе дали готовый инструмент, а не молоток и сказали: «Делай, что хочешь».
- Data Binding. Ах, да, если его использовать, то привязка данных становится почти магией. Написал в разметке
android:text="@{viewModel.userName}"— и всё, можно забыть проfindViewByIdи прочую рутину. Прям удивление пиздец, как жизнь упрощается.
А теперь про минусы, потому что без них никуда:
- Boilerplate-кода — овердохуища. Особенно если Data Binding не юзаешь. Ты пишешь ViewModel, потом в активити или фрагменте подписываешься на LiveData, обрабатываешь состояния... Иногда кажется, что ради одной кнопки ты пишешь код, как для запуска шаттла. Терпения ноль, ебать.
- Одноразовые события — головная боль. Ну вот представь: нужно показать тост, или перейти на другой экран, или открыть диалог. Это же событие, которое не должно повторяться, если, например, повернул экран. А LiveData-то свои данные хранит! И вот ты уже пляшешь с
SingleLiveEventилиSharedFlow, и чувствуешь себя полупидором, который из костылей и скотча систему собирает. - ViewModel-монстр. Если не следить, то вся логика приложения свалить в одну ViewModel — раз плюнуть. А потом она такая, на 1000 строк, и понять, что там происходит, может только манда с ушами. Надо дробить, выносить в юзкейсы, но это опять время и силы.
Ну и примерчик, чтобы не на словах было. Смотри, как просто выглядит:
class MyViewModel : ViewModel() {
// Вот это приватное, чтобы только внутри менять
private val _data = MutableLiveData<String>()
// А это публичное, только для чтения из View
val data: LiveData<String> = _data
fun loadData() {
// И вот тут мы меняем значение, и все, кто подписан — узнают
_data.value = "Hello MVVM"
}
}
Выглядит-то просто, да? Но это только цветочки. Когда начнёшь настоящую логику пихать, вот тогда и вспомнишь про хитрую жопу этой архитектуры. В общем, инструмент как инструмент. Умеешь им пользоваться — получится пиздопроебибна штука. Не умеешь — сами понимаете, хуй с горы.