Тимофей, спасибо большое за все Ваши видео! Актуальные темы излагаются просто, понятно и без "воды", поэтому уроки получаются очень полезными. Успехов Вам и Вашему каналу!
да, можно писать круто код, но если ты не умеешь объяснять так же, как и Тимофей, то я отказываюсь с тобой обсуждать разработку!) классно, друг. очень нравятся твои уроки, давай больше!)
На 30:40 вы говорите что параметры конструктора не могут быть приватными, но это не верно. Приватными не могут быть отдельные поля/методы, которые вы инжектите по отдельности с помощью аннотации @Inject. В случае с конструктором ограничение на приватность накладывается только на сам конструктор, т.е. нельзя написать @Inject private constructor(...). Но параметры конструктора (они же поля) могут быть приватными
Почти два дня и сидела и не могла правильни заинджектить зависимости с вьюмоделью в чистой архитектуре... Уже отчаялась к часу ночи, и наткнулась на это видео, сделала по образцу и заработало, спасибо вам за этот урок Т_Т Впереди ещё много всего предстоит понять, разобраться и доделать, но теперь у меня хотя бы что-то работает))
Шикарные видео! Пересматриваю каждые по несколько раз. Возник вопрос. В конце вы начинаете инжектить вьюмодели и юзкейсы через конструкторы, но разве юзкейсы не должны быть очищены от разных магических штук (в данном случае инжектов) для максимально прозрачного тестирования? Получается в конце чистая архитектура в данном проекте стала работать не на полную мощность…?
@@TimofeyKovalenko да, именно это, поворот экрана, уточнил для ясности!думал, если вьюмодель сложно в Даггер создать, и с поворотом данные не сохраняются, может я что-то не уловил!, хотя "мы" же фабрику используем) спасибо!
Так мы же там вью модель через дагер не предоставляем, мы фабрику получаем из дагера, а дальше используем стандартный подход. Что-бы получать VM от дагера нужно заморочиться, на мой вгляд это того не стоит, к тому же видел часто, где в проектах в итоге этих заморочек VM не работает, как должна.
А насколько корректно предоставлять вообще все зависимости через applicationContext? Получается же, что в нем будет скапливаться какое-то нереальное количество методов для каждого класса...
И есть такой общий вопрос по чистой архитектуре, почитал стать по этой теме (правда в контексте бэкенда а не андроида), в вашм примере entity/domain это классы содержащие только данные и больше походят на dto, но вроде как согласно ЧА entity могут содержать не только данные, но и поведение (Rich Domain Model). Вопрос, используется ли такая практика в андроид и если да то какие методы можно описать в entity?
При необходимости можно и поведение описать в ентити, тут никаких проблем нет, domain он как раз и создан, что-бы там было сосредоточено максимально много логики.
Здравствуйте. На 10 минуте возник вопрос Допустим у нас бы была ещё локальная БД, куда мы при желании также могли бы сохранять наши данные Получается у нас для UserRepository будет ещё один Storage(DBUserStorage например) Как сделать в даггере так чтобы он на давал тот UserStorage, который нам нужен?
Я не спец, но возможно следует немного переписать репозиторий, добавив в него больше абстракции. Таким образом репозиторию должно быть все равно с какой бд он работает
Если вы о том, что-бы репозиторий работал с разными Storage в зависимости от ситуации, то внимательно подумайте, действительно вам это нужно), как правило не нужно. Это может пригодится, если вы решили в проекте поменять способ хранения данных, например были файлы, а стала база данных. В этом случае Dagger не причем. Если все же хотите локально менять, то тоже не проблема, есть разные способы, например можно прописать ключи для провайдеров. А репозиторий мы не должны трогать, в этом и суть подобных архитектур, меняется только реализация необходимого класса и провайдеры.
Главный плюс кодо-генерации не только в том, что позволяет обнаружить ошибку на этапе компиляции, но и в том, что несмотря на то, что проект дольше билдится - он запускается гораздо быстрее у юзера, нежели Koin. У Koin нет кодо-генерации, граф зависимостей выстраивается по сути при запуске приложения, а вот у Dagger (благодаря кодо-генерации) - граф уже выстроен.
Спасибо за видео! В прошлых уроках говорили что SharedPrefUserStorage желательно сделать internal классом, как и наверное UserRepositoryImpl. Но если мы так сделаем, то не сможем провайдить их. Получается, что эти внутренние классы все равно видят другие модули, что нежелательно. Как этого избежать? Спасибо
Как минимум можно сделать провайдеры в data слое, которые вернут реализацию для DI. Но как правило в этом нет необходимости, потому, что о них знает только app. А если выносить функционал по разным модулям, то тем более это не проблема.
Почему в Provides-методе с Usecase в параметрах мы указываем интерфейс репозитория? А если у нас от одного интерфейса будет имплементироваться два репозитория? Аналогичная ситуация со Storag-ами. Объясните, пожалуйста, почему Вы используете интерфейсы в параметрах provides-методов, а не конкретный класс.
Просто в примере нет необходимости в нескольких реализациях, да и на практике это не так часто встречается. Всегда лучше применять по максимум интерфейсы вместо реализаций, если это возможно. А когда уже понадобится разбить на конкретные реализации, вот тогда можно и поменять.
Вопрос, все провайды находятся в модуле App, а если мне нужно будет что то инжектить в data то мне нужно создавать папку под Di и dagger модули в них отдельно для модуля data или их можно создавать так же app/di?
Имеете ввиду случай, когда data хочет что-то внутри себя инжектить? Имею ввиду инжектить что-то внутренне, а не то, что прихоит из другого модуля? Если да, то тут можно конечно затянуть dagger в data модуль, сделать в нем свой Module, в котором описать нужные провайдеры. Это вполне рабочий вариант, и так часто делают. Но я лично не очень люблю затягивать DI в модули, мне больше нравится, что-бы модули вообще никак не знали, как их будут создавать, и как конструировать, то есть все собираем в app снаружи, даже внутренние какие-то зависимости. Но нужно учитывать специфику проекта, если проект очень большой, особенно если с фича командами, то скорей всего у каждого модуля будет свой DI Module.
Тимофей, здравствуйте И просто понравилось и вопросы есть, но по дальнейшим видео Расскажите пожалуйста философию разбития на фиче модули как правильно и как не правильно и почему, хотя бы базу И расскажите про рх джаву пожалуйста. По ней дофига всего в инете что она вся очень крутая, но чем она лучше эвент бас, чем она лучше чем стартАктивитиФоРезалт (и подобного) почти нет. Чем она хороша для много модульных проектов? Спасибо
А причем здесь собственно "евент бас" и "стартАктивитиФоРезалт" ? Не знаю, насколько принципиален для вас выбор именно RxJava , но по моему мнению, лучше использовать корутины, а RxJava заносить в проект, если у вас есть на это какие-то жесткие требования/правила, обязующие использование именно RxJava или большой опыт использования их. С корутинами намного проще всё, читабельнее. Да и многие сторонние библиотеки, из коробки поддерживают работу с ними уже (а библиотеки из Jetpack так вообще, даже примеры использования у гугла давно демонстрируются с корутинами).
А по поводу фиче-модулей, то как правильно их разбивать, зависит от вас и вашей архитектуры проекта. Нужно определить для себя, что по вашему мнению есть фича?Многие держатся подхода, что фиче-модуль = это какой-то целый, завершенный экран вашего приложения. Можете зайти тоже с этой стороны. Но на сколько сильно вы решите дробить (разбивать) ваше приложение на фичи, и выносить их в отдельные модули, зависит только от вас и конкретно от вашего проекта. То есть нет единого правильного ответа именно под вас и прям так сразу, сходу..
@@tequilaonelove спасибо за ответ, меня интересует какие нибудь шаблоны и рекомендации от которых можно думать и делать под себя. Сейчас стоит вопрос больше научиться архитектуре для меня
Конечно можно написать, возможно даже короче выйдет. Но сколько других программистов будут понимать ваш подход? ). Поэтому с точки зрения развития проекта и надежности, на случай если вы решите уволиться, намного выгоднее применять популярные и устоявшиеся решения. Также делая свое решение вы перекладываете на себя обязанность поддерживать, исправлять и развивать этот код.