Курс на Stepik
Обложка курса «Корутины и Flow в Android: практический курс» на Stepik
1 390 ₽

Корутины и Flow в Android: практический курс 4.500

Открыть на
STEPIK.ORG

Вы шаг за шагом соберете полноценное приложение для изучения иностранных языков: Room, Retrofit, Jetpack Compose, реактивные потоки, offline-first синхронизация, лидерборд, система мотивации, статистика и навигация.

Показатель Текущие показатели Рост
Значение 🏆 Рейтинг 3 дн 7 дн 30 дн
Количество учеников на курсе «Корутины и Flow в Android: практический курс»Учеников на курсе 36
Сертификаты, выданные на курсе «Корутины и Flow в Android: практический курс»Сертификатов выдано 10
Отзывы о курсе «Корутины и Flow в Android: практический курс»Отзывов получено 2
Рейтинг курса «Корутины и Flow в Android: практический курс»Рейтинг курса 4.500
Уроки в курсе «Корутины и Flow в Android: практический курс»Количество уроков 36
Тесты в курсе «Корутины и Flow в Android: практический курс»Количество квизов 1
Время прохождения курса «Корутины и Flow в Android: практический курс»Время прохождения курса
Стоимость курса «Корутины и Flow в Android: практический курс»Стоимость курса 1 390 ₽
Обновления курса «Корутины и Flow в Android: практический курс»Обновления курса
Дата публикации курса «Корутины и Flow в Android: практический курс»Дата публикации курса
Последнее обновление курса «Корутины и Flow в Android: практический курс»Последнее обновление
Сложность normal
4.500
из 5
2 отзыва
★★★★★
1
★★★★
1
★★★
0
★★
0
0
Barmaley
Barmaley
2 месяца назад

Ставлю курсу твердую четверку. Что понравилось: 1) понравились некоторые интересные технические тонкости, которые интересно было "пощупать" через реальный код + вариант реализации паттерна Outbox 2) примеры с VM-фабриками были тоже очень познавательными. 3) примеры с combine да, очень хорошие - в коммерческих приложениях это главная "рабочая лошадка" :) Что не понравилось: 1) В паре мест автор дает идею и тут же отказывается от нее. Если идти по курсу последовательно, то в коде остаются ошибки, которые нужно исправлять самостоятельно. Так, например, было в SyncWorker, где автор попала в тупик собственного подхода - отказа от DI + хранения основных data-классов приложения (репозиториев) в MainActivity. Как мне кажется, курс смотрелся более выигрышно, если бы репозитории, БД и классы сетевого слоя хранились бы в отдельном Application-классе с ленивой инициализацией, а SyncWorker получал бы нужную ссылку через отдельный SyncWorkerFactory, например, так: class SyncWorkerFactory( private val repository: SyncRepository, ) : WorkerFactory() { override fun createWorker( appContext: Context, workerClassName: String, workerParameters: WorkerParameters ): ListenableWorker? { return when (workerClassName) { SyncWorker::class.java.name -> { SyncWorker(appContext, workerParameters, repository) } else -> null } } } а Application-класс определили бы как Configuration.Provider и добавили бы туда код: val syncRepository by lazy { SyncRepository( db = db, api = api, ) } override val workManagerConfiguration: Configuration get() = Configuration.Builder() .setWorkerFactory(SyncWorkerFactory(syncRepository)) .build() Ну и в целом, собирать конгломерат классов с ЖЦ уровня приложения внутри MainActivity - это не очень хороший пример. Учитывая, что курс могут проходить начинающие разработчики, я бы все-таки переработал код курса, чтобы плохие практики не перенимали ученики. 2) В проекте сделана не очень хорошая штука - классы распределяются по пакетам по типам, а не по функциональности. Например, VM-ки - в отдельный пакет "viewModel", dao-классы - в DAO и т.д. В крупных коммерческих приложениях так не делают никогда, потому что: а) Код пишут несколько команд и за каждым пакетом закрепляется свой оунер. Все кодоунеры перечислены в классе CODOWNERS и на код-ревью при изменении кода, закрепленного за отдельной командой, бот будет "тегать" именно того человека, который имеет отношение к измененном пакету в проекте. Если все VM-ки будут в одном пакете, начнется хаос - бот будет тегать всех подряд, включая людей из совсем других команд. б) фича не всегда пишется "на века". Например, сегодня в приложку добавили таблицу "leaderboard", а завтра у менеджмента зачешется левая пятка и скажут, что фича не востребована пользователями и ее нужно выпилить. Конкретно в случае этого проекта весь код удаляемой фичи нужно будет собирать по разным пакетам и удалять. А если фича хранится в отдельном модуле или пакете, то удаление для остальных команд будет максимально простым - просто дропнули нужный каталог и все. 3) В коде в нескольких местах есть ошибки + нет импортов, что делает менее удобным добавление кода - приходится тратить дополнительное время на ненужную работу.

Ответ
автора
Яна Седова
Яна Седова
1 июня 2026

Спасибо за развернутый отзыв! Отвечу тоже по пунктам: 1) От Hilt и подобных фреймворков я отказалась сознательно. Все же у нас учебный проект для новичков, а не продакшен-код. 2) Структура пакетов по типам выбрана осознанно по тем же причинам. Для новичка, который только разбирается в слоях архитектуры, пакет data/db нагляднее, чем пакет feature/lesson. 3) Я просмотрела все ваши комментарии к урокам, где содержатся указания на ошибки. Их всего 4, из которых 2 - где вы пытаетесь использовать шаблонный код IDE вместо кода из урока, 1 - вызвана отсутствием у вас импорта и только последняя, действительно, является ошибкой (спасибо, я ее исправила). Если у вас есть информация еще о каких-то ошибках в коде, прошу писать комментарии под конкретными уроками, чтобы я могла проверить. 4) Импорты намеренно не указаны: они утяжеляют примеры, у большинства настроен автоимпорт, а если нет — то всегда можно нажать Alt+Enter. 5) SyncWorker приведен просто для примера, в качестве лирического отступления. Не думаю, что ради него стоит переписывать весь курс на Hilt/Dagger.