Skip to content
Источник

ViewModel и init

Наткнулся на первую статью из серии best practices для работы с ViewModel. Очень похоже по стилю на что-то гугловое, из-за чего я купился, но, слава богу, нет. В ней автор говорит, что init секцию в ViewModel использовать не рекомендуется для инициализации состояния. Да, так и написано, init не использовать для инициализации ✏️. Аче всмысле? Я заинтересовался.

Говорит это на первый взгляд кажется удобно, но у этого есть минусы. Ок, давайте по порядку.

  • Tight Coupling with ViewModel Creation. В этом суть init блока, ало, если мы что-то в нём инициализируем, то мы хотим, чтобы что-то проинициализировалось на старте, тут связь абсолютно логичная.
  • Testing Challenges. Говорит сложно тестить VM, ведь вы там на старте запросов в интернет понапишете, флаковать будет. Ну, моки подложи, в тестах настоящие запросы делать это ты сам себе злобный буратино. И в чём проблема протестить состояние после создания её инстанса не совсем понятно.
  • Limited Flexibility. А вдруг, говорит, вы захотите грузить данные не на старте, а после какого-то события. Чел, во-первых "вдруг" это так себе аргумент, во-вторых я тогда просто вынесу содержимое init блока в функцию и всё, в чём проблема то?
  • Handling Configuration Changes. Тут, говорит, если вы что-то напишете в init блоке, то смена конфигурации может привести к неожиданному поведению или ненужному переполучению данных и всё такое. Это чего вдруг? Сам же пишет, что ViewModel на conf change не пересоздастся. То есть init вызывется один раз, то есть и данные придут тебе один раз.
  • Resource Management и UI Responsiveness. Говорит, всё что напишем в init в главном потоке работает, поэтому вызовет тормоза и лишнее потребление ресурсов. Опять же да, в этом суть, ты хочешь проинициализировать что-то сразу. Хочешь, чтобы какой-то стейт у тебя по умолчанию собрался, чтобы какой-то запрос сразу дёрнулся и так далее. Ты там делаешь что-то лёгкое, чтобы не ждать пока вьюшка даже отрисуется, это на "производительности" приложения только в лучшую сторону скажется, не говоря уж о том, что это первоначальное состояние ты без морганий сможешь нарисовать.

А предлагает то что? Предлагает переписать простой и понятный код, где в init блоке в viewModelScope какая-то загрузка дёргается на какие-то реактивные цепочки типа flow{...}.stateIn() и stateFlow.asLiveData().switchMap{...} в пропертях. Что или сомнительно, или как раз не скейлится на более комплексные вьюмодельки, или не универсальное решение, т.е. в каждом случае тебе нужно разное решение придумывать. init прекрасен тем, что тебе думать не надо, ты пишешь простой (почти) синхронный код в любом своём сценарии. На функции только разбивать не забывай, чтобы понятно было, да и всё.

И я вообще не понимаю зачем это всё, он обходит придуманные им самим ограничения. Пища для размышлений, конечно, какая-то есть, но что аргументами, что решениями меня не убеждает совсем. Я что-то упускаю или на медиуме опять хайпит дичь? 🤔