Ответ
В Android-разработке рекомендуется использовать интерфейс для репозитория. Это позволяет:
- Легко подменять реализацию (например, мок для тестов)
- Соблюдать принцип инверсии зависимостей (DIP)
- Упрощать поддержку кода
Пример:
interface UserRepository {
suspend fun getUser(id: String): User
}
class UserRepositoryImpl(
private val api: UserApi,
private val dao: UserDao
) : UserRepository {
override suspend fun getUser(id: String): User {
// Реализация с кешированием
}
}
Прямая реализация без интерфейса допустима в простых случаях, но усложняет тестирование и модификацию кода.
Ответ 18+ 🔞
Э, слушай, а вот тут реально интересный момент. Некоторые думают, что интерфейсы для репозиториев — это овердохуища лишней писанины. Мол, зачем, если можно сразу класс написать и не париться?
Ну так вот, чувак, я тебе щас объясню, какого хуя это всё-таки нужно. Представь, ты написал репозиторий, который сразу лезет в сеть и в базу. Всё в одном флаконе. И вроде бы работает. А потом приходит время писать тесты. И тут ты такой: "Ёпта...". Потому что чтобы протестировать твой экран, тебе нужно поднимать либо реальный сервер (смешно), либо городить костыли. А с интерфейсом ты просто подсовываешь мок, который возвращает тестовые данные, и всё, ты уже тестируешь логику, а не работу сети. Доверия ебать ноль к тем, кто говорит, что это лишнее.
Вот смотри на этот кусок кода, тут всё правильно:
interface UserRepository {
suspend fun getUser(id: String): User
}
class UserRepositoryImpl(
private val api: UserApi,
private val dao: UserDao
) : UserRepository {
override suspend fun getUser(id: String): User {
// Реализация с кешированием
}
}
Красота же! UserRepositoryImpl — это хитрая жопа со всей бизнес-логикой: сначала глянул в кэш, потом, если надо, в сеть сходил, результат обновил. А в тестах у тебя будет FakeUserRepository, который просто из памяти данные отдаёт. И твой ViewModel или UseCase нихуя не заметит подмены, потому что он с интерфейсом работает. Это и есть тот самый принцип инверсии зависимостей — высокоуровневые модули не зависят от низкоуровневых, а зависят от абстракций. Звучит заумно, но на деле просто спасает жопу.
Конечно, если у тебя пет-проект на коленке или какой-нибудь разовый скрипт, то да, можешь и без интерфейса. Прямая реализация — и да похуй. Но как только проект начинает расти, появляется второй экран, третий, нужны тесты... Вот тут-то ты и вспомнишь этот совет, но будет поздно, переделывать придётся овердохуища кода. Лучше сразу приучить себя к правильной архитектуре, чтобы потом не было мучительно больно, блядь.
Так что не будь тем самым распиздяем, который потом орет "да кто так архитектуру-то проектирует!". Начинай с интерфейса, и будет тебе счастье.