Записаться ко мне на индивидуальные занятия или групповые курсы по Android можно на: ✅ KIPARO.COM. СОДЕРЖАНИЕ: 00:00:00 - пару вводных слов ;) 00:00:32 - показываю проблему на диаграмме с Clean Architecture 00:02:59 - что такое DI (Dependency injection) 00:03:45 - Dagger 00:04:31 - Hilt 00:05:09 - Koin 00:06:57 - Koin в Android на практике 00:17:00 - добавление MVVM в Koin 00:20:56 - конфигурация и старт Koin 00:24:53 - рисуем DI в диаграмме ;) 00:26:39 - итоги
не знаю, почему так мало просмотров и лайков. Один из самых понятных циклов по архитектуре, что я видел. Я джун и только на этом цикле начал полностью врубаться, как должен работать clean architecture
Спасибо за видео! Для любого студента большое счастье, когда в преподавателе сочетаются знание предмете и методологический талант. Продолжайте пожалуйста расширять тематику Ваших видеоуроков. Для нас (надеюсь, что это общее мнение) будут интересны любые темы в Вашем изложении! Конечно желаю творческих успехов.
Спасибо огромное за видео, у вас очень хороший педагогический подход - смотрите на вещи глазами студента,... все легко и понятно, продолжайте пожалуйста!!!! Если возможно, то хотелось бы видео про ООП, SOLID, DRY, ....flow тоже очень интересен
Лучший плейлист по Андроиду из всего что есть на Ютубе. Раньше казалось что архитектура, di, mvvm это что-то сложное, что нужно долго это все изучать. Большое спасибо, хотелось бы еще увидеть это все на чуть более сложном проекте.
Тимофей, вы очень крутой! Спасибо вам за структурность и последовательность объяснений! Всё понимается с первого просмотра, ну разве что несколько раз назад перематываешь)
22:35 при "androidLogger(Level.DEBUG)" приложение крашится с ошибкой "java.lang.NoSuchMethodError: No static method toDouble-impl(JLjava/util/concurrent/TimeUnit;)...". Если заменить на "androidLogger(Level.ERROR)" - нормально запускается.
А у меня крашилось с Found interface kotlin.time.TimeMark, but class was expected .... Спасибо, натолкнули на мысль Debug поменял на Error, и запустилось.
Очень вовремя мне скинули ссылку на ваш курс. Все было понятно и доходчиво, спасибо) После сдачи проекта, возьмусь смотреть с первых видео этого листа)
Спасибо за видео, в первые слышу о DI, в учебе не сталкивался с проблемой зависимостей. Теперь вижу что koin простой, но концепцию нужно еще распробовать на практике.
Я как раз вчера искал уроки на тему Koin на русском их можно сказать и нет. На английском не все понятно к сожелению, прям вовремя не то слово. Видео только начел смотреть, но уверен все норм обьясниш судя по ранее записанным видео. Прям канал выручалочка))
Огромное спасибо приятно учиться когда так подробно всё объясняют Немного жалею что взял один курс а теперь понимаю что надо было брать у вас. К сожалению не без этого))
Тимофей,спасибо за видео,очень полезно. Хотел у вас спросить: когда может понадобиться использовать factory {} вместо single {}?. Почему обычно use cases создают через factory {}? Почему бы не юзать все время single {}?Спасибо
factory используют, когда необходимо создавать разные инстансы (экземпляры) одних и тех же зависимостей. single - когда необходимо иметь один и тот же экземпляр класса, в разных частях/экранах вашего приложения. Допустим у вас есть два экрана в приложении и один какой-нибудь объект, который может хранить в себе какое-нибудь состояние/данные. Возмем к примеру ту же самую вьюмодель. На одном экране вы подписываетесь на какую-нибудь livedata из вашей вьюмодели. И на другом экране проделываете тоже самое. Если вы отметили вашу вьюмодель как single, то на двух ваших фрагментах(экранах), в случае восстановления/ перевороте экрана, вы будете получать одно и то же состояние и одни и те же данные. Если вы отметили вашу вью модель как factory, то на двух фрагментах у вас будет создано два разных экземпляра вьюмодели. И весь ваш стейт будет различный. Ваш первый фрагмент будет иметь свой экземпляр вьюмодельки и никак не влиять на другой второй фрагмент. Конечно у коина так же есть скоупы, которые позволяют разрулить жизненный цикл ваших зависимостей, относительно того, жив ли допустим ваш экран или нет. При этом сценарии, зависимости указанные как single и привязанные к какому то скоупу, будут все равно уничтожаться и пересоздаваться, ровным счётом также, как factory.
Ага. Если только ваше приложение состоит из одного экрана и 1-го модуля ) Когда вы решите сделать многомодульное приложение, с десятками экранов, то это уже не будет выглядеть как отличная замена. Особенно когда начнёте получать ошибки предоставления зависимостей в рантайме, а не на момент компиляции кода =)
Koin отлично живет в больших проектах. Ошибка рантайм - да, есть такое, но это обходится тестами, например у меня на большом проекте за несколько лет ни разу не вылезла такая ошибка в продакшене.
Может там null у какой-то переменной, которую распечатываете или логгер совсем не логгер - проверьте правильный ли импорт. А так лучше скиньте текст ошибки, без этого невозможно помочь.
Замечательное видео спасибо огромное за разъяснение! 1:46 подскажите когда 50 UseCase их наверное как то делят по папкам? Я сейчас набросал в редакторе схем, получилось 9 UseCase мне их сразу раскладывать в папки к которым они логически относятся?
Тимофей, спасибо за качественный материал. Однако есть такой вопрос: для чего вся эта Clean Archeticture? Функционал приложения с первого урока в этом плэйлисте не изменился почти никак (за исключением сохранения данных при поворотах во вьюхах благодаря ViewModel). В остальном код многократно усложнился, наплодилось просто гигантское количество сущностей (методов, классов, моделей, сторонних библиотек и т.д.). Почему такая структура считается понятнее и проще для других программистов (как Вы объясняли в начале)? Лично меня она приводит в ужас и кажется крайне сложной и запутанной. Признаюсь, что не работал в больших компаниях разработчиком, только свои проекты, но уже достаточно долго. Решил вот пополнить знания и попробовать себя в роли разработчика в какой-нибудь компании в дальнейшем.
У нас не стояло задачи добавить новый функционал, поэтому да, функции все те же. С архитектурой всегда так, больше кода, но взамен получаешь более гибкое приложение. Задача всего этого сделать так, что бы когда у тебя много экранов, функционала, много разработчиков на проекте, была возможно все это обслуживать и менять, без риска сломать остальные части приложения. Также, такая архитектура помогает связать руки разработчикам, и избежать хард кода, когда хочется побыстрому что-то запилить с мыслями когда-нибудь потом исправить))). Что-бы на практике понять плюсы архитектуры - любой, не важно клин или еще что то, нужно пожить на одном проекте длительное время, хотя бы года два, тогда наглядно будут понятны все преимущества. Часто разработчики приходят и уходят))), не заботясь о том, что будет дальше после них, поэтому без опыта и не видят смысла в архитектуре.
Здравствуйте Тимофей. Вопрос по поводу инициализации ViewModel. Даже в не большем проекте будет около 50 Fragments/Activity у каждого есть ViewModel. Для того чтобы Koin подцепил все зависимости при использовании by viewmodels, все эти ViewModels должны быть объявлены в models{}? Есть ли в Koin аналогичные Hilt annotation?
Да, все должно быть в models{}. В целом, мне лично, подход с явным объявлением провайдеров больше нравится, можно легко найти все провайдеры для моделей в одном месте. Но приходится платить за это размером кода. Такого как в Hilt в Koin нет.
@@TimofeyKovalenko Спасибо за ответ. Тогда какие best practices в случае много модульного проекта? Например: ест модуль UI в нем есть models{}, модуль UI видит модуль app. Как передают models из UI в app для выполнения startKoin()?
Спасибо за ценные уроки, смотрю с удовольствием 🤩Есть один вопрос у меня, у нас в app module мы добавили и domain, и data, чтобы смогли создать дерево DI и предоставить объекты storage, repository, usecase... Но правильно ли, что app module видит data слой тоже? 🤔 И если брать в учет, что у нас могут быть и другие модули, то выходит app module имеет доступ ко всем их)
В нашем случае app module содержит presentation, поэтому да, технически можно достучатся до data из presentation. Что бы этого избежать, нужно разделять app module и presentation.
Спасибо за видео! Во время моей работы с Koin, у меня возник вопрос. Ранее я уже работал с Dagger 2 и обычно хранить модуль вьюмодели на уровне компонента App там было не вполне нормально, для этого был ActivityComponent, а то и FragmentComponent, если ВМ привязана к одному фрагменту в сингл-активити приложении. Здесь получается все модули так или иначе будут обьявлены в App и подключить дополнительный Component c модулями в Активити или Фрагменте не выйдет. Или я ошибаюсь?
Здрастуйте, спасибо за понятное изложение информации! на пальцах как говорится) С юзкейсами и репозиториями в коине все понятно. Как использовать DataStore в koin? ViewModels без фабрик и пустым конструктором тоже в di? Ещё записался к вам на индивидуальные курсы, с нетерпением жду ответа.
Здравствуйте, спасибо за такие отличные уроки, возникла проблема, что если ставлю androidLogger(Level.DEBUG) приложение крашит с непонятной ошибкой, но если поставить androidLogger(Level.NONE) то всё отлично работает, это же не нормально ?
Для чего разделять Koin DI на отдельные модули App, Data, Domain, если они всё равно инициализируются в Application и подтягивают друг друга? Какое практическое применение такого разделения в реальных проектах (понятно,что здесь просто пример)? Или это в данном случае чисто для читаемости?
В реальном проекте зависимостей очень много, и часто разделяют даже на большее число модулей, что-бы читабельность была нормальная. Иначе будет полотно из кода на сотни строк
Здравствуйте Тимофей, у меня возник к вам вопрос, совместимы ли Clean Architecture и библиотека для пагинации Paging 3? Я обучаюсь на андроид разработчика на языке Kotlin, и у меня возник этот вопрос, т.к. domain слой не должен быть зависим от сторонних библиотек, как я понимаю.
Paging 3 это либа из androidx, в домене ее не должно быть. Поэтому тут нужно использовать свои объекты в домене и пейджинг использовать только на presentation. Я бы ее вообще не использовал, реализовать пейджинг задача не сложная и вполне можно обойтись своим кодом.
Извините, я наверно прослушал. Не могу понять такую штуку. Получается два одинаковых класса User и UserName, и ещё name сохраняется через SaveUserNameParam. С другой стороны цель применения такой архитектуры - независимость частей кода. Разве не придётся делать изменения в этих трёх классах при изменении одного из них? И разве не сломается при этом приложение? Хотелось бы увидеть, при добавлении в класс User или UserName каких-то полей, приложение не ломается и требуется немного изменений. Спасибо, с уважением.
В том то и суть, что каждый слой может добавить туда что-то, не затрагивая другие зависимости. Тоесть работает только со своим объектом. А если глобально что то нужно будет добавить, то да, нужно будет добавить на всех уровнять, точнее добавить поддержку в каждой из частей индивидуально.
Из за androidLoggin вылетает приложение. NoSuchMethodError: No static method toDouble-impl(JLjava/util/concurrent/TimeUnit;)D in class Lkotlin/time/Duration; or its super classes (declaration of 'kotlin.time.Duration
@@TimofeyKovalenko (опечатался, Logger). Да, верно, полностью копирую Ваш пример. Стоит закоментить строчку androidLogger(Level.Debug) (которая на 23:15) и все работает. Странно, может какой-то глюк AndroidStudio.
Здравствуйте Тимофей, это не относится к теме данного видео, но все же у меня возник этот вопрос при создании многомодульного проекта. Вопрос заключается в следующем: В модуль какого типа ложить package "base" - там где находятся BaseFragment, BaseRepository и т.д.? И может ли domain имплементировать интерфейс с base.
BaseFragment и BaseRepository - очень плохая практика. Особенно BaseFragment -, от этого лучше избавиться, что-бы у вас не было базовых классов для фрагментов или активити. Ну а если без этого никак, то у вас должен быть какой-то core модуль, например core-presentation где будут находится общие ресурсы для ваших модулей.
В течении жизни проекта в них копиться очень много кода, и в итоге получается так, что все экраны очень жестко зависят от кода базового фрагмента. Истории про то, что все мы умные и ничего туда лишнего закидывать не будет полная ерунда ;), через пару лет базовый фрагмент в проекте превратиться в спагетти.Да и наследование само по себе усложняет код, поэтому лучше этого избегать.
@@TimofeyKovalenko Здравствуйте,Тимофей.Почему BaseFragment - плохая практика?Да и вообще,почему базовые классы с общней логикой являются плохой практикой,когда они позволяют нам избегать повторяющегося кода?(DRY - Don't repeat yourself). К тому же базовые классы помогают в инкапсуляции,позволяют не открывать наружу константы,чтобы делать их доступными для всех,можно сделать константы protected и там,где они будут нужны унаследоваться от Base класса.
@@TimofeyKovalenko особенно когда нужен простой фрагмент, а описывать вроде бы всё заново лень.. Смотришь, ого - есть же BaseFragment, и наследуешься от него. А потом у нас все фрагменты живут по принципу: И жнец и швец и на дуде игрец ))
Для Koin вполне подходят файлы, это же по сути тот же статик будет только без объекта, нет необходимости именно object писать. И так и так можете делать.
@@TimofeyKovalenko это тонкий намек на то что вы осветили лишь императивный ui в compose нужна udf архитектура. И Koin там чуть по другому работает. P. s. Хотелось бы увидеть просветление этой темы.
У меня из-за строчки logged возникает ошибка " No static method toDouble-impl(JLjava/util/concurrent/TimeUnit;)D in class Lkotlin/time/Duration; or its super classes (declaration of 'kotlin.time.Duration' appears in /data/app/~~_-1rZ0YNIhro1xGls3dajA==/com.example.daggertest2--M5UP5kSUyc5xEwdUJyhPA==/base.apk) at org.koin.core.time.MeasureKt.measureDuration(Measure.kt:32)" Прочитал в интернете, что там какие-то конфликты в новой версии котлина с этим логгером. Как это можно пофиксить? Возможно какую-то версию Я использовал коин 3.1.2 и котлин 1.7
Записаться ко мне на индивидуальные занятия или групповые курсы по Android можно на: ✅ KIPARO.COM.
СОДЕРЖАНИЕ:
00:00:00 - пару вводных слов ;)
00:00:32 - показываю проблему на диаграмме с Clean Architecture
00:02:59 - что такое DI (Dependency injection)
00:03:45 - Dagger
00:04:31 - Hilt
00:05:09 - Koin
00:06:57 - Koin в Android на практике
00:17:00 - добавление MVVM в Koin
00:20:56 - конфигурация и старт Koin
00:24:53 - рисуем DI в диаграмме ;)
00:26:39 - итоги
Это просто золотые уроки. Сколько людей, который уже стали супер программистами, но они вообще не умеют доносить свою мысль простыми словами
не знаю, почему так мало просмотров и лайков. Один из самых понятных циклов по архитектуре, что я видел. Я джун и только на этом цикле начал полностью врубаться, как должен работать clean architecture
Ролики по образованию в целом не особо популярная тема.
Аналогично. Учусь и разбираю, объяснение просто замечательные
Чтобы собрать просмотры и лайки, нужно кидать ментос в колу
Программирование это как в сказке, чем дальше, тем страшнее. Огромное спасибо за подробные объяснения
Спасибо за видео! Для любого студента большое счастье, когда в преподавателе сочетаются знание предмете и методологический талант. Продолжайте пожалуйста расширять тематику Ваших видеоуроков. Для нас (надеюсь, что это общее мнение) будут интересны любые темы в Вашем изложении! Конечно желаю творческих успехов.
Спасибо огромное за видео, у вас очень хороший педагогический подход - смотрите на вещи глазами студента,... все легко и понятно, продолжайте пожалуйста!!!! Если возможно, то хотелось бы видео про ООП, SOLID, DRY, ....flow тоже очень интересен
спасибо) буду ждать видос по даггер)
Просто шикарные уроки, объяснения, наверное лучшие на ютубе..
Лучший плейлист по Андроиду из всего что есть на Ютубе.
Раньше казалось что архитектура, di, mvvm это что-то сложное, что нужно долго это все изучать.
Большое спасибо, хотелось бы еще увидеть это все на чуть более сложном проекте.
Да, будет обязательно пример на более сложном проекте.
Первое видео, которое понятно объяснило суть DI и Koin. Низкий поклон, лайк и подписка
Посмотрел ваши уроки по clean architecture, все максимально понятно. Особенная благодарность за визуализацию=)
Очень многие вещают,не учитывая вложенность одной темы, технологии в другую,отсюда порой применимость инфы минимальна. А Вам респект!
Тимофей, вы очень крутой! Спасибо вам за структурность и последовательность объяснений! Всё понимается с первого просмотра, ну разве что несколько раз назад перематываешь)
Грамотный текст, внятный четкий голос - что еще надо для хорошей учебы )
Это максимально поелзное видео. Смогла внедрить Koin в свой pet-проект. Спасибо вам большое!
👍
Такой тип архитектуры сейчас востребован на рынке. На одном из интервью меня спрашивали именно ее. Благодарю за четкое и понятное объяснение.
У вас талант! Четкая дикция, грамотное объяснение! Делайте больше таких видео!
22:35 при "androidLogger(Level.DEBUG)" приложение крашится с ошибкой "java.lang.NoSuchMethodError: No static method toDouble-impl(JLjava/util/concurrent/TimeUnit;)...". Если заменить на "androidLogger(Level.ERROR)" - нормально запускается.
У меня та же самая ошибка вышла, методом тыка решил, интересно, почему через дебаг крашиться приложение
Ребята, спасибо большое, что пишите про ошибки в комментариях. Прям очень помогли. У меня та же ошибка
А у меня крашилось с Found interface kotlin.time.TimeMark, but class was expected .... Спасибо, натолкнули на мысль Debug поменял на Error, и запустилось.
Очень вовремя мне скинули ссылку на ваш курс.
Все было понятно и доходчиво, спасибо)
После сдачи проекта, возьмусь смотреть с первых видео этого листа)
Спасибо за видео, в первые слышу о DI, в учебе не сталкивался с проблемой зависимостей. Теперь вижу что koin простой, но концепцию нужно еще распробовать на практике.
Толково, интересно, познавательно. Большое спасибо!
Спасибо за видео.Коммент в поддержку!
Я как раз вчера искал уроки на тему Koin на русском их можно сказать и нет. На английском не все понятно к сожелению, прям вовремя не то слово. Видео только начел смотреть, но уверен все норм обьясниш судя по ранее записанным видео. Прям канал выручалочка))
глянул видео первым. очень круто!) теперь буду clean architecture познавать)))
Как всегда все супер понятно и супер полезно! Спасибо Вам! ❤🔥
Топовые ролики, смотрю всю серию по архитектуре от начала, огромное спасиба за доступный материал!
Спасибо очень хорошие уроки по чистой архитектуре вы объясняете понятно и доходчиво))
Супер!
Спасибо огромное за ваш труд !!! Невероятно хорошее объяснение, обожаю такие форматы где сначала лектор делает ошибку а потом исправляет ее )
Уроки - огонь. С ними себя увереннее чувствуешь :)
спасибо за подробный и четкий разбор этой темы)
Большое спасибо автору. Очень подробно объясняете. Подписался, буду смотреть дальше.
Все просто и максимально доступно объяснено. Спасибо)
пожалуйста, публикуйте видео чаще хотя бы раз в неделю
Огромное спасибо приятно учиться когда так подробно всё объясняют
Немного жалею что взял один курс а теперь понимаю что надо было брать у вас. К сожалению не без этого))
Такая лаконичная библиотека, супер облегчает
Спасибо!) Очень вовремя! Ждем еще видео по архитектуре!
Тимофей, спасибо за ваши уроки. Снова захотелось учиться!
Спасибо, тёзка. Отличный курс!
Очень интересно, спасибо!
Выглядит попроще, чем Hilt, видимо, потому что аннотации не требуются
Спасибо огромное) За 20 минут научился как работать с Koin)
Курс огонь! Спасибо большое за знания 🤗
Спасибо!!!
Спасибо за ваш труд, все очень понятно объясняете.
Хороший комментарий для приятного ощущения :)
Тимофей, спасибо за этот плейлист
Большое спасибо)
Тимофей,спасибо за видео,очень полезно. Хотел у вас спросить: когда может понадобиться использовать factory {} вместо single {}?. Почему обычно use cases создают через factory {}? Почему бы не юзать все время single {}?Спасибо
factory используют, когда необходимо создавать разные инстансы (экземпляры) одних и тех же зависимостей.
single - когда необходимо иметь один и тот же экземпляр класса, в разных частях/экранах вашего приложения.
Допустим у вас есть два экрана в приложении и один какой-нибудь объект, который может хранить в себе какое-нибудь состояние/данные. Возмем к примеру ту же самую вьюмодель.
На одном экране вы подписываетесь на какую-нибудь livedata из вашей вьюмодели. И на другом экране проделываете тоже самое.
Если вы отметили вашу вьюмодель как single, то на двух ваших фрагментах(экранах), в случае восстановления/ перевороте экрана, вы будете получать одно и то же состояние и одни и те же данные.
Если вы отметили вашу вью модель как factory, то на двух фрагментах у вас будет создано два разных экземпляра вьюмодели. И весь ваш стейт будет различный. Ваш первый фрагмент будет иметь свой экземпляр вьюмодельки и никак не влиять на другой второй фрагмент. Конечно у коина так же есть скоупы, которые позволяют разрулить жизненный цикл ваших зависимостей, относительно того, жив ли допустим ваш экран или нет. При этом сценарии, зависимости указанные как single и привязанные к какому то скоупу, будут все равно уничтожаться и пересоздаваться, ровным счётом также, как factory.
Спасибо вам за уроки!
Просто вау👍👍
Великолепно!
как то так прсто все), что кажеться, что не чего не понял) но показано и обьеснено, все очень просто и понятно)
Огонь!!!!
Спасибо. Очень все понятно.
вы очень хорошо обяснили
"Это просто песня какая-то!" выглядит действительно как отличная замена через чур громозкого Dagger'а
Ага. Если только ваше приложение состоит из одного экрана и 1-го модуля ) Когда вы решите сделать многомодульное приложение, с десятками экранов, то это уже не будет выглядеть как отличная замена. Особенно когда начнёте получать ошибки предоставления зависимостей в рантайме, а не на момент компиляции кода =)
Koin отлично живет в больших проектах. Ошибка рантайм - да, есть такое, но это обходится тестами, например у меня на большом проекте за несколько лет ни разу не вылезла такая ошибка в продакшене.
Здравствуйте Тимофей когда будет новое видео?
мы ждем с нетерпением
Вот вот, уже в процессе).
нормальная тема - на примере сервис-локатора показывать, чтт такое депенденси-инджекшн
Лучший!
👍
У меня почему-то, если использовать андроид логгер, то приложение при запуске падает(
Может там null у какой-то переменной, которую распечатываете или логгер совсем не логгер - проверьте правильный ли импорт. А так лучше скиньте текст ошибки, без этого невозможно помочь.
Тоже самое, import правильный
UserCase классы теперь можно удалять?
какой-то хороший комментарий)))
Замечательное видео спасибо огромное за разъяснение! 1:46 подскажите когда 50 UseCase их наверное как то делят по папкам? Я сейчас набросал в редакторе схем, получилось 9 UseCase мне их сразу раскладывать в папки к которым они логически относятся?
Да, просто поделите папками и все.
Хороший комментарий.
Тимофей, спасибо за качественный материал.
Однако есть такой вопрос: для чего вся эта Clean Archeticture? Функционал приложения с первого урока в этом плэйлисте не изменился почти никак (за исключением сохранения данных при поворотах во вьюхах благодаря ViewModel). В остальном код многократно усложнился, наплодилось просто гигантское количество сущностей (методов, классов, моделей, сторонних библиотек и т.д.). Почему такая структура считается понятнее и проще для других программистов (как Вы объясняли в начале)? Лично меня она приводит в ужас и кажется крайне сложной и запутанной. Признаюсь, что не работал в больших компаниях разработчиком, только свои проекты, но уже достаточно долго. Решил вот пополнить знания и попробовать себя в роли разработчика в какой-нибудь компании в дальнейшем.
У нас не стояло задачи добавить новый функционал, поэтому да, функции все те же. С архитектурой всегда так, больше кода, но взамен получаешь более гибкое приложение. Задача всего этого сделать так, что бы когда у тебя много экранов, функционала, много разработчиков на проекте, была возможно все это обслуживать и менять, без риска сломать остальные части приложения. Также, такая архитектура помогает связать руки разработчикам, и избежать хард кода, когда хочется побыстрому что-то запилить с мыслями когда-нибудь потом исправить))).
Что-бы на практике понять плюсы архитектуры - любой, не важно клин или еще что то, нужно пожить на одном проекте длительное время, хотя бы года два, тогда наглядно будут понятны все преимущества. Часто разработчики приходят и уходят))), не заботясь о том, что будет дальше после них, поэтому без опыта и не видят смысла в архитектуре.
Здравствуйте Тимофей.
Вопрос по поводу инициализации ViewModel.
Даже в не большем проекте будет около 50 Fragments/Activity у каждого есть ViewModel.
Для того чтобы Koin подцепил все зависимости при использовании by viewmodels, все эти ViewModels должны
быть объявлены в models{}?
Есть ли в Koin аналогичные Hilt annotation?
Да, все должно быть в models{}. В целом, мне лично, подход с явным объявлением провайдеров больше нравится, можно легко найти все провайдеры для моделей в одном месте. Но приходится платить за это размером кода. Такого как в Hilt в Koin нет.
@@TimofeyKovalenko Спасибо за ответ. Тогда какие best practices в случае много модульного
проекта? Например: ест модуль UI в нем есть models{}, модуль UI видит модуль app. Как передают
models из UI в app для выполнения startKoin()?
app модуль ничего не должен знать про UI модуль. Зачем вам в app передавать зависимости ViewModel?
Спасибо за ценные уроки, смотрю с удовольствием 🤩Есть один вопрос у меня, у нас в app module мы добавили и domain, и data, чтобы смогли создать дерево DI и предоставить объекты storage, repository, usecase... Но правильно ли, что app module видит data слой тоже? 🤔 И если брать в учет, что у нас могут быть и другие модули, то выходит app module имеет доступ ко всем их)
В нашем случае app module содержит presentation, поэтому да, технически можно достучатся до data из presentation. Что бы этого избежать, нужно разделять app module и presentation.
Класс
Хороший коментарий)
оставляю хороший комментарий ;)
Спасибо за видео! Во время моей работы с Koin, у меня возник вопрос. Ранее я уже работал с Dagger 2 и обычно хранить модуль вьюмодели на уровне компонента App там было не вполне нормально, для этого был ActivityComponent, а то и FragmentComponent, если ВМ привязана к одному фрагменту в сингл-активити приложении. Здесь получается все модули так или иначе будут обьявлены в App и подключить дополнительный Component c модулями в Активити или Фрагменте не выйдет. Или я ошибаюсь?
Ошибаетесь. В Koin тоже можно делать отдельные компоненты для экранов или фичей и загружать/выгружать их по необходимости
Здрастуйте, спасибо за понятное изложение информации! на пальцах как говорится)
С юзкейсами и репозиториями в коине все понятно.
Как использовать DataStore в koin?
ViewModels без фабрик и пустым конструктором тоже в di?
Ещё записался к вам на индивидуальные курсы, с нетерпением жду ответа.
Стараюсь всем отвечать, но уж очень много заявок, физически не успеваю всем быстро ответить.
Здравствуйте, спасибо за такие отличные уроки, возникла проблема, что если ставлю androidLogger(Level.DEBUG) приложение крашит с непонятной ошибкой, но если поставить androidLogger(Level.NONE) то всё отлично работает, это же не нормально ?
У меня та же ошибка, тоже не могу понять, почему ее выдает
Для чего разделять Koin DI на отдельные модули App, Data, Domain, если они всё равно инициализируются в Application и подтягивают друг друга? Какое практическое применение такого разделения в реальных проектах (понятно,что здесь просто пример)? Или это в данном случае чисто для читаемости?
В реальном проекте зависимостей очень много, и часто разделяют даже на большее число модулей, что-бы читабельность была нормальная. Иначе будет полотно из кода на сотни строк
А возможно для полного понимания увидеть полный код? Просто не хочется ради одного кусочка видео, смотреть и вручную писать код со всего плэйлиста
Видео так же использую и для студентов, поэтому код не выкладываю, иначе все просто копирнут, запустят и ничего не сделают сами ;).
spasibo ochen
Привет! Этот тестовый проект можете куда-нибудь выложить?
Нет, иначе студенты потом сами это не пишут и результат не очень хороший :). Просто эти видео использую в том числе и для обучения.
Здравствуйте Тимофей, у меня возник к вам вопрос, совместимы ли Clean Architecture и библиотека для пагинации Paging 3?
Я обучаюсь на андроид разработчика на языке Kotlin, и у меня возник этот вопрос, т.к. domain слой не должен быть зависим от сторонних библиотек, как я понимаю.
Paging 3 это либа из androidx, в домене ее не должно быть. Поэтому тут нужно использовать свои объекты в домене и пейджинг использовать только на presentation.
Я бы ее вообще не использовал, реализовать пейджинг задача не сложная и вполне можно обойтись своим кодом.
Извините, я наверно прослушал. Не могу понять такую штуку. Получается два одинаковых класса User и UserName, и ещё name сохраняется через SaveUserNameParam. С другой стороны цель применения такой архитектуры - независимость частей кода. Разве не придётся делать изменения в этих трёх классах при изменении одного из них? И разве не сломается при этом приложение? Хотелось бы увидеть, при добавлении в класс User или UserName каких-то полей, приложение не ломается и требуется немного изменений. Спасибо, с уважением.
В том то и суть, что каждый слой может добавить туда что-то, не затрагивая другие зависимости. Тоесть работает только со своим объектом.
А если глобально что то нужно будет добавить, то да, нужно будет добавить на всех уровнять, точнее добавить поддержку в каждой из частей индивидуально.
Из за androidLoggin вылетает приложение. NoSuchMethodError: No static method toDouble-impl(JLjava/util/concurrent/TimeUnit;)D in class Lkotlin/time/Duration; or its super classes (declaration of 'kotlin.time.Duration
А где вы используете androidLoggin? Так же как в примере?
@@TimofeyKovalenko (опечатался, Logger). Да, верно, полностью копирую Ваш пример. Стоит закоментить строчку androidLogger(Level.Debug) (которая на 23:15) и все работает. Странно, может какой-то глюк AndroidStudio.
Хм, я думаю дело не в Logger. Из за этой строчки не должно падать, скорей всего проблема не здесь.
Спасибо, мне кажется хилт попроще будет)
У всех свои плюсы есть, мне лично koin больше нравится)
обязательный комментарий который я тут оставлю))
Здравствуйте Тимофей, это не относится к теме данного видео, но все же у меня возник этот вопрос при создании многомодульного проекта. Вопрос заключается в следующем: В модуль какого типа ложить package "base" - там где находятся BaseFragment, BaseRepository и т.д.? И может ли domain имплементировать интерфейс с base.
BaseFragment и BaseRepository - очень плохая практика. Особенно BaseFragment -, от этого лучше избавиться, что-бы у вас не было базовых классов для фрагментов или активити.
Ну а если без этого никак, то у вас должен быть какой-то core модуль, например core-presentation где будут находится общие ресурсы для ваших модулей.
@@TimofeyKovalenko а по какой причине BaseFragment и ему подобные это плохая практика?
В течении жизни проекта в них копиться очень много кода, и в итоге получается так, что все экраны очень жестко зависят от кода базового фрагмента. Истории про то, что все мы умные и ничего туда лишнего закидывать не будет полная ерунда ;), через пару лет базовый фрагмент в проекте превратиться в спагетти.Да и наследование само по себе усложняет код, поэтому лучше этого избегать.
@@TimofeyKovalenko Здравствуйте,Тимофей.Почему BaseFragment - плохая практика?Да и вообще,почему базовые классы с общней логикой являются плохой практикой,когда они позволяют нам избегать повторяющегося кода?(DRY - Don't repeat yourself). К тому же базовые классы помогают в инкапсуляции,позволяют не открывать наружу константы,чтобы делать их доступными для всех,можно сделать константы protected и там,где они будут нужны унаследоваться от Base класса.
@@TimofeyKovalenko особенно когда нужен простой фрагмент, а описывать вроде бы всё заново лень.. Смотришь, ого - есть же BaseFragment, и наследуешься от него. А потом у нас все фрагменты живут по принципу: И жнец и швец и на дуде игрец ))
Насколько хорошей практикой является хранить модули в простых файлах? Где-то видел, что модули хранят в объектах. Как лучше сделать?
Для Koin вполне подходят файлы, это же по сути тот же статик будет только без объекта, нет необходимости именно object писать. И так и так можете делать.
хороший комметарий
А как koin будет жить в jetpac Compose
Так же как и сейчас ;), или что вас смущает в сompose?
@@TimofeyKovalenko это тонкий намек на то что вы осветили лишь императивный ui в compose нужна udf архитектура. И Koin там чуть по другому работает.
P. s. Хотелось бы увидеть просветление этой темы.
Да, сделаю такое видео).
красава
Its perfectly
Merci
У меня из-за строчки logged возникает ошибка " No static method toDouble-impl(JLjava/util/concurrent/TimeUnit;)D in class Lkotlin/time/Duration; or its super classes (declaration of 'kotlin.time.Duration' appears in /data/app/~~_-1rZ0YNIhro1xGls3dajA==/com.example.daggertest2--M5UP5kSUyc5xEwdUJyhPA==/base.apk)
at org.koin.core.time.MeasureKt.measureDuration(Measure.kt:32)"
Прочитал в интернете, что там какие-то конфликты в новой версии котлина с этим логгером. Как это можно пофиксить? Возможно какую-то версию
Я использовал коин 3.1.2 и котлин 1.7
Такая же беда, все как в видео, но крашится бесконечно.
Попробуй поставить Level.None, тогда ничего не крашится.
@@alexandralban5682 Попробуй поставить Level.None, тогда ничего не крашится.
Спасибо!
Спасибо!!