Замечания: - Compose ))) - Либо использовать интерфейс как интерфейс либо уже полноценно функцию высшего порядка) - Вместо Adapter использовать ListAdapter - ViewModel для данных - ViewBindingPropertyDelegate
Содержит бизнес‑логику, должен быть независим от деталей реализации приложения и внешних библиотек (можно делать исключения, пример RxJava, DI Framework)
Можно делать исключение в случае если это языковые либы, например для того же DI если вы используете Koin или для асинхронщины Kotlin Coroutines.
Не совсем корректно то что в domain модуль имплементируется зависимость Hilt так как она напрямую из Android, а domain модуль не должен зависить ни коим образом от платформенных зависимостей и должен быть чисто языковым модулем Java/Kotlin, так как вам нужны тот же @Inject @Singleton , а Hilt поддерживает JSR-330, правильнее будет использовать зависимость Javax.Inject и так же DI module'и мне кажется правильнее выносить в какой di модуль либо в ту же app'ку, так как di не ответственность этих модулей, собственно в остальном все по теме) ??
Привет, да тоже столкнулся с проблемами по Deep Link'ам с разными build variant'ами. Думали сделать через разные файлы graph'ов либо strings для каждого build type'a, но это бы ещё больше проблем создало. Смогли все таки решить, можно сделать такую реализацию:
Обязательно к нашему host'у НЕ должна быть добавлена scheme=app в AndroidManifest далее нам нужно <deepLink ... /> в nav_graph указывать таким образом:
app:uri="https://.*/path"
Очень полезная ссылка на тред в stackoverflow, мне кажется при создании статьи тоже изучали его.
Привет, обоснование такое то что да вы правильно сказали это вообще не секьюрно так делать. Писал в конце постскриптум
P. S. Конечно же это все чисто для примера. На странице авториации никогда нельзя отображать ошибку в инпутах, все должно отображаться в Toast, но это все для примеров :). Снизу ссылки на репозитории.
Тут нет какой-то общей логики рабочего приложения все исключительно для примеров :)
Насчет излишне усложенности, не сказал бы по одной причине того что на практике было приложения в котором часто использовались инпуты и каждый раз это все производить вручную закончилось бы плохо, пришлось автоматизировать в результате вот что получилось.
Спасибо! Сам что-то не додумался до этого перемудрил тогда получается. Ещё раз спасибо, скорее всего обновлю статейку и добавлю обновление в репозиторий. ?
А вопрос если захочу кастомно обработать ошибку правильнее ли будет добавить в этот же код ещё раз catch
override fun fetchFoo() = doRequest {
service.fetchFoo().toDomain().also {
// do something in success
}
}.catch { exception ->
// do something in error
}
Для себя выучил, что наследование — последнее, к чему надо прибегать.
Можно уточнить почему? Впринципе понял скорее всего тогда возьму и выведу
А хотелось бы узнать почему вам видиться метод doSomethingInSuccess лишним. Я хочу вам дать такой кейс. Сделали мы такую функцию как doRequest окей сделали по нему запрос, но эти данные нам нужно каким-то образом сохранить куда-то в результате как мы можем это все разграничить и правильно написать? Вижу я это вот так в своей реализации:
class SignInRepositoryImpl @Inject constructor(
private val service: SignInApiService,
private val userData: UserData
) : BaseRepository(), SignInRepository {
override fun signIn(userSignIn: UserSignIn) = doRequest(this::setupSignInSuccess) {
service.signIn(userSignIn.fromDomain()).toDomain()
}
private fun setupSignInSuccess(signIn: SignIn) {
// Сохраняем здесь токен в SharedPreferences или же DataStore для дальнейшего использования
userData.saveToken(signIn.token)
}
}
Хотелось бы услышать от вас как бы вы реализовали эту логику?
А насчет internal top функции согласен с вами можно и так вынести, но просто изначально в коде ещё есть такой же метод для запроса с пагинацией. Просто не видел смысла выносить.
А почему результат игнориться вы внимательно если посмотрите там нужно сохранять определенные данные в SharedPreferences, думаю это не обоснованные придирки ). Насчет flow избытычен можно и без этого return'ить, но как уже добавлялось это самый простой кейс для того чтобы показать сами запросы ;)
Можно ещё вспомнить переход с ButterKnife на Kotlin синтетики, а потом на ViewBinding
Актуальный вопрос, зачем статья ради статьи?)
Замечания:
- Compose )))
- Либо использовать интерфейс как интерфейс либо уже полноценно функцию высшего порядка)
- Вместо Adapter использовать ListAdapter
- ViewModel для данных
- ViewBindingPropertyDelegate
Если будет полезно можете заглянуть сюда по реализации clean'a стараюсь частенько его обновлять
Можно делать исключение в случае если это языковые либы, например для того же DI если вы используете Koin или для асинхронщины Kotlin Coroutines.
Не совсем корректно то что в domain модуль имплементируется зависимость Hilt так как она напрямую из Android, а domain модуль не должен зависить ни коим образом от платформенных зависимостей и должен быть чисто языковым модулем Java/Kotlin, так как вам нужны тот же
@Inject @Singleton
, а Hilt поддерживает JSR-330, правильнее будет использовать зависимость Javax.Inject и так же DI module'и мне кажется правильнее выносить в какой di модуль либо в ту же app'ку, так как di не ответственность этих модулей, собственно в остальном все по теме) ??Привет, да тоже столкнулся с проблемами по Deep Link'ам с разными build variant'ами. Думали сделать через разные файлы
graph
'ов либоstrings
для каждого build type'a, но это бы ещё больше проблем создало. Смогли все таки решить, можно сделать такую реализацию:Обязательно к нашему
host
'у НЕ должна быть добавленаscheme=app
вAndroidManifest
далее нам нужно<deepLink ... />
вnav_graph
указывать таким образом:app:uri="https://.*/path"
Очень полезная ссылка на тред в stackoverflow, мне кажется при создании статьи тоже изучали его.
Код в результате:
AndroidManifest.xml
nav_graph.xml
А так да, проблем было очень много, спасибо большое за статью ❤️
Тут нет какой-то общей логики рабочего приложения все исключительно для примеров :)
Насчет излишне усложенности, не сказал бы по одной причине того что на практике было приложения в котором часто использовались инпуты и каждый раз это все производить вручную закончилось бы плохо, пришлось автоматизировать в результате вот что получилось.
А вопрос если захочу кастомно обработать ошибку правильнее ли будет добавить в этот же код ещё раз catch
Можно уточнить почему? Впринципе понял скорее всего тогда возьму и выведу
А хотелось бы узнать почему вам видиться метод
doSomethingInSuccess
лишним. Я хочу вам дать такой кейс. Сделали мы такую функцию какdoRequest
окей сделали по нему запрос, но эти данные нам нужно каким-то образом сохранить куда-то в результате как мы можем это все разграничить и правильно написать? Вижу я это вот так в своей реализации:Хотелось бы услышать от вас как бы вы реализовали эту логику?
А насчет internal top функции согласен с вами можно и так вынести, но просто изначально в коде ещё есть такой же метод для запроса с пагинацией. Просто не видел смысла выносить.