Next Level Dev
680 subscribers
32 photos
2 videos
58 links
Заметки синьора-самоучки с 10-летним опытом

Доучиваю или учу с нуля до крепкого джуна, готового к собеседованиям и стажировке

Roadmap для начинающих в личке @ilia_a_popov
Там же запись на менторство и консультации

О менторстве: https://androidmentor.ru
Download Telegram
Ответ на вопрос подписчика

Вопрос по архитектуре: в каких случаях нужно создавать отдельную ViewModel и репозиторий? Возьмём за пример простенькое приложение, где есть три основные фичи: просмотр изображений, фильтрация их по категориям и добавление их в избранное.

Для каждой фичи нужно создавать ViewModel и репозиторий или раз все между собой тесно связано, лучше использовать один на все приложение, а отдельные создавать только для чего-то очень слабо связанного между собой.

Но если и для избранного и для фильтрации и тд использовать только одну ViewModel, не нарушает ли это single responsibility principle?


Ответ: Single responsibility principle – принцип единственной ответственности. Чтобы ему следовать, нам надо сначала понять, а какая ответственность у вьюмодели и репозитория?

На самом деле, на этот вопрос, как и на большинство вопросов по архитектуре, нельзя ответить однозначно, потому что подходы могут быть разные: кому-то нравится делать вьюху максимально пассивной, кому-то нет, но я вам расскажу подход, которому следую я, которому следуют в моей компании и которому я всех учу.

Ответственность репозитория: это управление источниками данных, их обработка и предоставление наружу в обработанном виде. Репозиторий ходит в сеть, кэширует, достаёт из кэша, маппит сетевые модели в доменные, обрабатывает ошибки, при необходимости маппит их в бизнесовые ошибки. Репозиторий отвечает за какой-то определённый кусок логики, например UserRepository или ImagesRepository.

Ответственность вьюмодели: вьюмодель – это прослойка между бизнес-логикой и определённым экраном. То есть вьюмодель не к фичам привязана, а к экрану. Если у вас на экране есть и добавление в избранное и фильтрация, значит и во вьюмодели это будет. Но вьюмодель делает это не сама, она обращается в вашем случае к конкретному репозиторию и получает из него результат. А репозитории вы уже проектируете как вам удобно: Например FavoritesRepository и FilterRepository, если хотите эту логику отделить. Или можете сделать один ImagesRepository, если не хотите отделять.

И запомните: однажды вам захочется сделать печально известную SharedViewModel и пошерить её между несколькими экранами. Это приведёт вас на путь, наполненный запутанным и нерасплетаемым спагетти-кодом, куче костылей и конфликтов. Не делайте так. Один экран – одна вьюмодель.

#android #архитектура #вопросы

Запись на менторство:
@andrdevnotes | androidmentor.ru
👍9🔥4💯21
Привет, друзья!

Разбирая ваши запросы, заметил, что много практических вопросов по коду. Пришла в голову идея: устроить стрим с разбором ваших проектов.

Формат: вы до 19 мая присылаете мне ссылку на репозиторий со своим проектом. Я из них отбираю 5 проектов на разбор.

И я с 20 до 31 мая провожу один или больше стримов (в зависимости от объёма проектов) с подробным разбором и советами по рефакторингу.

Если у вас получится присутствовать на стриме – отлично, сможем лично пообщаться по проекту. Нет – посмотрите в записи.

Стоимость: 1990р за 1 проект.

Как вам идея?
👍43🔥2
Офигеваю от того, как быстро вы отвечаете 🙂

Раз желающих много, проведу несколько стримов. Один стрим = 3-5 проектов
Проекты кидайте в личку: @ilia_a_popov

Первый стрим будет 21-го мая в 19-00
Привет, друзья!

Помимо долгосрочного менторства на 1, 2, 3 месяца, о котором можно подробнее почитать на androidmentor.ru, я также даю почасовые консультации под конкретный запрос.

Один из вариантов – тренировочное собеседование: либо основное техническое, по Java / Kotlin / Android, либо алгоритмическая секция с лайвкодингом на leetcode.com.

На скриншотах отзыв о последних двух моих собеседованиях.

Если хотите тоже попробовать свои силы – записывайтесь на индивидуальную консультацию @ilia_a_popov

#android #собеседование #консультация

@andrdevnotes | androidmentor.ru
👍61🔥1👀1
Привет, друзья!

Напоминаю, что 21-го мая у нас стрим с разбором ваших проектов. Некоторые уже прислали свои проекты, некоторые пока нет. Не оттягивайте до последнего ;)

@andrdevnotes | androidmentor.ru
🔥3👍1👌1
Next Level Dev pinned Deleted message
Что делать, если всё пошло не по плану

Жизнь разраба – это не всегда модные кафешки, макбуки и смешные мемчики. Иногда разраб обсирается, причём по полной программе. Но крут не тот, кто не ошибается, а кто на ошибках учится.

Я сегодня планировал провести стрим с разбором проектов подписчиков. Было 14 желающих, но проект прислал в итоге только 1 человек. Супер-респект ему за смелость, он получит от меня бесплатную консультацию по его проекту в подарок.

Это косяк номер раз 🙂

Не беда, думаю я, сделаю стрим с лайвкодингом. Покажу, как с нуля написать проект, подключить сервисы, сделать всё по красоте. Новичкам точно будет полезно. Но не тут-то было :)) Ютуб решил проверить мой канал прежде, чем давать возможность проводить трансляции. Поэтому я вынужден перенести стрим на 28 мая.

Это косяк номер 2.

Но этот канал я заводил не для красивых постов, а для того, чтобы писать всё, как есть.

Так же и в работе: разработчики часто сталкиваются с тем, что что-то идёт не так: новые сборки не прошли тестирование, продакты не согласовали раскатку, или фичу, над которой вы корпели месяцами, пользователи встретили негативными комментариями и поливают говном вашу компанию.

Плохо ли это?

Нет, это нормальный процесс. Иногда надо ошибаться, тупить, косячить, чтобы понять, как что устроено. А иногда негатив – это просто реакция на что-то резко новое. Поэтому важно учиться, не сдаваться, и воспринимать ошибки, как подарок, как спортзал для наших мышц 🙂

Такие дела, друзья.

Ну что, проводим стрим с лайвкодингом в следующий вторник?

Ставь + в комментариях, если интересно.

#мотивация
👍16🔥6👏1
LiveData vs Flow: одноразовые ивенты и стейты

Начинающие разработчики часто путаются между LiveData и Flow. Для каких случаев подходит одно, а для каких – другое?
👀2🐳1
LiveData позволяет нам держать во вьюмодели стейт, который мы можем наблюдать из вьюхи. Стейт – это некая динамическая переменная, отвечающая за состояние какой-то сущности. Например – LiveData<List<Item>>, в которую будет приходить список, который мы хотим отобразить во вьюхе. Вьюха наблюдает LiveData и реагирует на каждое изменение этого списка, всегда отображая актуальные данные.

ViewModel:
private val _items: MutableLiveData<List<Item>> = MutableLiveData()
val items: LiveData<List<Item>> = _items

View:
viewModel.items.observe(viewLifecycleOwner) {
adapter.submitList(it)
}


Преимущество LiveData в том, что она присылает свои изменения в наблюдателя с учётом его жизненного цикла, и нам об этом париться не надо. Да и в целом, LiveData – простая штука, хорошо работающая "из коробки", и позволяющая легко на начальных этапах реализовать наблюдаемый стейт для MVVM.

Недостаток LiveData в том, что это класс из android-пакета, и использовать его, скажем, в domain-слое по клину не очень-то хорошо, особенно если есть прицел на мультиплатформенность.

Flow позволяет нам реализовывать куда более гибкие и управляемые наблюдаемые конструкции, без привязки к android-пакету. Flow можно создавать самому, делая туда эмиты тогда, когда нужно, и настраивая так, как удобно. Его можно делать и холодным и горячим, доступным для одного подписчика или для многих, и многое другое.

ViewModel:
private val navigationEvents = MutableSharedFlow<NavigationEvent>(replay = 1)

View:
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.navigationEvents.collect {...}
}
}


Недостаток Flow в том, что его не стоит использовать, не почитав документацию и не разобравшись. Из коробки он может не во всех кейсах работать интуитивно понятно. По незнанке довольно легко можно, к примеру, наткнуться на ситуацию, когда у вас Flow "зависает" и перестаёт эмитить, и даже блокирует ваш поток, не давая исполняться коду, который написан в корутине вне Flow после вызова collect.

К чему может привести неверное использование LiveData: если пытаться её использовать для, скажем, навигационных событий (показать / скрыть диалог или перейти на экран), сначала может показаться, что всё работает, но потом вы поймёте, что при смене конфигурации или возврате на экран мы будем получать старые данные (поскольку LiveData держит стейт), или ловить другие странные баги.

Поэтому запомните: нужны одноразовые события – используйте для них Flow. А LiveData – для простых стейтов, напрямую связанных с UI.

#лайфхаки #android

Другие полезные посты

Обучение android-разработке:
@andrdevnotes | androidmentor.ru
👍6🔥41
💥 Первый стрим на канале 💥

Пишем приложение с нуля!

🔜 Завтра, во вторник 28 мая, в 19:00 я на ваших глазах буду пилить андроид-приложение на основе одного из публичных API.

📱Стек: XML, REST, MVVM, MultiModule Clean, Hilt, Glide, Room, ViewBinding, Gson, Coroutines, Retrofit.

Это стандартный стек для большинства проектов в индустрии. Понимая этот стек, с остальным разобраться труда не составит.

В процессе постараюсь объяснять, что делаю, и время от времени отвечать на вопросы.

Стрим будет идти ориентировочно 1.5 - 2 часа.

Не знаю, буду ли я такой стрим повторять, так что советую не пропускать =)

https://youtube.com/live/7zLXaXsTS2o?feature=share
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥15👀3👌21
Фууууууух!

Первый стрим – всё 🐸
Волновался аки школьник

А прикиньте, вот так на собесе лайвкодят) Для этого и надо тренироваться)

Спасибо всем, кто был, мне было очень приятно. За поддержку всем отдельный респект! Димон, жму руку:)

Ну что, как вам стрим? :) Делаем ещё?

Пишите в комменты отзывы/пожелания! 🏃‍♂️

Если остались вопросы – тоже пишите, на все обязательно отвечу.

Запись стрима

#стрим #видео #android #livecoding
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13👏74🤝3😁1
Один из мощных плюсов андроид-разработки

Я в индустрии 10 лет, бывал и разработчиком на C++, и на Java, и сайты / веб-приложения делал на HTML / CSS / JS, и бэкенд и нейронки на python. Это я к тому, что мне есть с чем сравнивать android-коммьюнити. И я не перестаю удивляться, насколько оно всё-таки крутое.

Вот пример: те, кто были на моём стриме, уверен, почувствовали то же, что и я: единение. Мы все были заодно, все боролись над одной задачей, и все одерживали маленькие победы, все испытывали облегчение и радость после того, как получалось победить ошибки.

У нас есть замечательный чат Android Developers, в котором много людей, готовых бесплатно подсказывать и помогать. И это куда быстрее, полезнее и приятнее, чем идти на StackOverFlow и выслушивать, какой же ты тупой.

Я уверен, что Android – уникальная платформа, которая своей гибкостью и сложностью объединяет вокруг себя разработчиков. Будь она простой для освоения – коммьюнити не было бы таким дружным. Мы все бьёмся против общего "врага" ! И с каждой закрученной гуглом гайкой, с каждым очередным усложнением фоновой работы мы становимся всё дружнее и сильнее. Нас не победить!)

И знаете что? Так далеко не везде.

#android #мотивация
🔥12👍52🥰2
❇️ Два простых способа сохранить данные при перезапуске приложения ❇️

Рассказываю про SharedPreferences и DataStore.
P.S.: а для особо внимательных задание: найдите на видео моего помощника =)

Приятного просмотра! 🚀

Мне будет приятно, если поддержите лайками и комментариями 👀

https://youtu.be/A_1dnLqZdsY?si=vIygP7xoJEB8lIRv

#android #видео #лайфхаки

@andrdevnotes | androidmentor.ru
👍6🔥21👏1🤩1
Настало время планировать следующую неделю!

В четверг 20 июня в 19-00 нас ждёт вторая серия стрима "Создаём проект с нуля". На этой серии стримов мы пишем приложение для отображения списка персонажей из Rick and Morty.

В прошлой серии мы успели сделать:
– первичную структуру: 3 модуля, пакеты-заглушки
– сетевой слой для запроса списка персонажей (без пагинации)
– маппер, ретрофит и репозиторий
– для всего вышеперечисленного сделали инъекцию зависимостей хилтом
– простейшую вёрстку через RecyclerView и ListAdapter с DiffUtil и отображение списка через вьюмодель

Дальше у нас в планах:
– перенести логику во фрагменты
– завезти ViewBinding
– добавить в элементы списка картинку с помощью Glide
– пагинация и бесконечный скролл с лоадером и пулл-ту-рефрешем
– обработать клик по картинке с переходом на DetailsFragment
– кэширование: InMemory и Persistent (Room)

Репозиторий

Закидывайте в комментарии ваши предложения по тому, что хотелось бы увидеть на стриме!

А кто смотрел предыдущий стрим – напишите в комментариях на youtube, что понравилось или не понравилось. Это важно для продвижения канала :)
👍63🥰1🆒1
Виды кэширования

1️⃣ In-Memory Cache
Это кэш, который живёт вместе с приложением, перезапуск он не переживает.

Типичная реализация – синглтон, в переменных которого вы сохраняете нужную информацию.

Плюсы: быстрое чтение и запись, не надо морочиться с БД.

Минусы: нет всех плюсов хорошей обёртки над БД типа Room, всё надо делать самому руками. Да и тяжёлые данные в In-memory кэше забивают память и могут усложнять использование кэша.

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

2️⃣ Persistent Cache
Это кэш, который переживает приложение, сохраняясь в памяти устройства.

Чаще всего это или уже знакомые вам преференсы, или Room, который я буду завозить в наше приложение на стриме в четверг.

Плюсы: удобное и гибкое использование через Room, переживает перезапуск, хорошо оптимизирован для хранения и чтения больших и сколь угодно сложно связанных данных.

Минусы: медленнее, чем просто достать данные из памяти приложения, и надо потратить время, чтобы разобраться.

Чаще всего в приложении используются оба типа кэша, а как ими управлять, сколько каждый из них живёт по времени и тд – ответственность репозитория.

#android #лайфхаки

@andrdevnotes | androidmentor.ru
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥21🫡1